So I have Users model namespaced:
namespace App\Models;
use Phalcon\Mvc\Model;
class Users extends Model
{
And Controller:
use \Phalcon\Mvc\Controller;
use \App\Models\Users;
class LoginController extends Controller
{
...
public function postLoginAction() {
$user = Users::findFirst([ ...
}
...
Always getting error Fatal error: Uncaught Error: Class 'App\Models\Users' not found in no matter what, tried every variation no idea what's wrong with it. even my IDEA resolving this class correctly.
Everything is working if I remove my namespacing.
UPDATE:
So if you generated project with phalcon dev tools and then started generate other things (model, controllers) you will need to provide namespace for model and it will not work, you will also need to update app/config/loader.php like this:
<?php
$loader = new \Phalcon\Loader();
/**
* We're a registering a set of directories taken from the configuration file
*/
$loader->registerDirs(
[
$config->application->controllersDir,
$config->application->modelsDir
]
)->register();
$loader->registerNamespaces(
[
'App\Controller' => $config->application->controllersDir,
'App\Model' => $config->application->modelsDir,
]
)->register();
In other words register namespace, I don't know why this not clearly stated in documentation but it seams this framework have many such "black holes" or I don't understand this framework fundamentals (came from codeigniter and Laravel background).
Try this in your bootstrap file:
// registers namespaces
$loader = new Loader();
$loader->registerNamespaces([
'App\Controllers' => APP_PATH . '/controllers/',
'App\Models' => APP_PATH . '/models/'
]);
$loader->register();
Btw, APP_PATH could be a constant to your app's directory, or whatever you want/need.
Related
I'm trying to create modules in Codeigniter 4 to work with HMVC. I tried following this user guide https://codeigniter4.github.io/userguide/general/modules.html, but cannot get it working.
I created a 'modules' folder, alongside the app, public, etc. folders.
Added to app/config/autoload.php
'Modules' => ROOTPATH.'modules'
Inside the modules folder, I created a 'Proef' folder, containing a Controllers folder and 'Proef.php' file.
The file contains the following;
namespace App\Modules\Proef\Controllers;
class Proef extends \CodeIgniter\Controller
{
public function index() {
echo 'hello!';
}
}
In the app/config.routes.php file I added
$routes->group('proef', ['namespace' => 'Modules\Proef\Controllers'], function($routes)
{
$routes->get('/', 'Proef::index');
});
Yet, the following error persists:
Controller or its method is not found: \Modules\Proef\Controllers\Proef::index
What am I missing?
If you put your modules folder "alongside" and not under your app folder, then your namespace is wrong.
So you would have something like
app/
Modules/ ==> can be modules or Modules but must be set in autoload with the same case
Proef/
Controllers/
Proef.php
NOTE: modules can be Modules or modules but the corresponding entry in the autoload must match.
For modules
'Modules' => ROOTPATH . 'modules'
For Modules
'Modules' => ROOTPATH . 'Modules'
It appears (from my limited testing) that the other folder names must
be 1st letter Upper case. This is under Apache on Linux.
let's use Modules for the folder name so in Autoload.php we would have...
$psr4 = [
'App' => APPPATH, // To ensure filters, etc still found,
APP_NAMESPACE => APPPATH, // For custom namespace
'Config' => APPPATH . 'Config',
'Modules' => ROOTPATH . 'Modules'
];
So your Proef Controller - Proef.php ... Note the namespace being used.
<?php
namespace Modules\Proef\Controllers;
use App\Controllers\BaseController;
class Proef extends BaseController {
public function index() {
echo 'Hello - I am the <strong>'. __CLASS__ . '</strong> Class';
}
}
To make this accessible via the URL you can set the routes (Routes.php) to... (simple version)
$routes->get('/proef', '\Modules\Proef\Controllers\Proef::index');
To make it callable within other Controllers... ( I have borrowed Home.php for this)
<?php namespace App\Controllers;
use \Modules\Proef\Controllers\Proef;
class Home extends BaseController
{
public function index()
{
$mProef = new Proef();
$mProef->index();
return view('welcome_message');
}
//--------------------------------------------------------------------
}
In your URL -
/proef will result in the just the message
/home will result in the class message and the welcome page.
So hopefully this will help you figure this out. its a lot of fun :)
Aside:
You can put your Modules Folder anywhere. I put mine under app/ for ole times sake, which removes the need to add the entry in Autoload.php as they fall under app/ which is already defined.
The namespace and use statement need to be changed appropriately as well.
Edit
namespace to Modules\Proef\Controllers in Proef class
I am trying to create the library inside the vendor folder in ZF2. Here is the structure:
/Vendor
/Mylib
/Mylib.php
/MylibStore.php
/MylibError.php
....
I have declared the same lib in Applicaiotion/Module.php:
public function getAutoloaderConfig()
{
return array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
'Mylib' => __DIR__ . '/../../vendor/Mylib',
),
),
);
}
Now I am calling Mylib class in controller it is working but when I am trying to instantiate other class in controller it is giving the error. Here is snap of code:
Mylib.php
namespace Mylib;
abstract class Mylib
{
MylibStore.php
namespace MylibStore;
use \Mylib\MylibError;
class MylibStore extends MylibError
{
MylibError.php
namespace MylibError;
class MylibError
{
I am getting the following error :
Fatal error: Class 'MylibStore\MylibError' not found in
C:\xampp\htdocs\coxaxle\vendor\Mylib\MylibStore.php on line 5
Please let me know what I am doing wrong? And how can I resolve this issue?
Problem is in your namespaces. All your files inside Mylib directory should have same namespace- Mylib.
That's why only Mylib class works, because it has correct namespace.
If you put your classes in separate directories then you have to update namespace about this directory.
Example:
/Vendor
/Mylib
/Service
/MylibService.php
/Mylib.php
....
Class Mylib should have namespace Mylib
Class MylibService should have namespace Mylib\Service
Here is my app structure:
/application
/config
/library
/Foo
/Controler.php
/module
/User
/config
/src
/Bar
/Controler
/BarController.php
/public
/vendor
/init_autoloader.php
The Controler.php file...
namespace Foo_Controller;
use Zend\Mvc\Controller\AbstractRestfulController;
class Foo_Controller extends AbstractRestfulController {
protected $foo;
public function getFoo()
{
return "foooo";
}
function __construct()
{
parent::__construct();
$foo = $this->getFoo();
}
}
The BarController.php...
namespace Bar\Controler;
use Zend\Mvc\Controller\AbstractRestfulController;
use Foo_Controller\Foo_Controller;
use Zend\View\Model\JsonModel;
class BarController extends Foo_Controller {
.
..
....
}
Added the path /library folder in the init_autoloader.php
$loader = include 'vendor/autoload.php';
$zf2Path = 'vendor/zendframework/zendframework/library';
$loader->add('Zend', $zf2Path);
$loader->add('Julia', 'library'); // added the library folder
if (!class_exists('Zend\Loader\AutoloaderFactory')) {
throw new RuntimeException('Unable to load ZF2. Run `php composer.phar install` or define a ZF2_PATH environment variable.');
}
I get an error 500 with the following:PHP Fatal error: Class 'Foo_Controller\Foo_Controller' not found in /application/module/Bar/src/Bar/Controller/BarController.php on line #
I really don't know what to do now. I have been searching the internet for some time now for the correct way to extend a controller class in Zend Frazmework 2, but i can't seem to grasp it!
What am i doing wrong in the app?
Thank you
I would suggest you set this out slightly differently. Would really make more sense to create your own custom module which you can load into any project with directory structure like:
/zf2-MyCustomModule
/src
/MyCustomModule
/Controller
/Abstract
/MyAbstractController.php
namespace for MyAbstractController.php would be - MyCustomModule\Controller\Abstract
If it is specific to the project then why not just add
/Abstract
/MyAbstractController.php
to the User Module Controller dir.
but seems like what you have done is pretty much right you would just need to update namespace in Foo_Controller.php to:
namespace Julia\Foo\Controller;
not
namespace Foo_Controller;
Though I have never used the method you are using so am not 100% sure.
I would add a new local config to /config/autoload/
like /config/autoload/namespaces.global.php
Zend\Loader\AutoloaderFactory::factory(array(
'Zend\Loader\StandardAutoloader' => array(
'namespaces' => array(
'Julia' => __DIR__ . '/Library',
),
)
));
then your namespace should still be Julia\Foo\Controller;
I hope that someone will be able to help me as I've been going a little crazy trying to get this to work. I have done numerous searches online and find tidbits of information, but unfortunately, I can't seem to get to a solution.
I'm trying to achieve the following in Phalcon with multiple modules.
MasterController extends Controller
BackendController extends MasterController
ModuleController extends BackendController
ClientsController extends ModuleController
The folder structure I have is this:
apps
|->crm
|-->controllers
|--->ModuleController
|--->ClientsController
common
|->controllers
|-->MasterController
|-->BackendController
Now in my Modules.php file under CRM I have the following:
$loader->registerNamespaces(
array(
'Multiple\Crm\Controllers' => __DIR__ . '/controllers/',
'Multiple\Crm\Models' => __DIR__ . '/models/',
'Multiple\Crm\Plugins' => __DIR__ . '/plugins/',
'Multiple\Common\Controllers' => __DIR__ . '/../../common/controllers/'
)
);
My ModuleController file looks like this:
class ModuleController extends Multiple\Common\Controllers\BackendBase
{
public function onConstruct()
{
echo "hello";
}
}
Whenever I run the code, I end up with the following fatal error:
Fatal error: Class 'Mulitple\Common\Controllers\BackendBase' not found in /var/www/phalcon/html/apps/crm/controllers/ModuleController.php on line 8
I have tried numerous things, but I cannot seem to get it to work. Can anyone shed some light on this and tell me what I'm doing wrong?
Many thanks in advance.
After reviewing the comments by #cvsguimaraes and #NikolaosDimoploulos I took the option to "start again". I used the phalcon devtools to generate the basis of the structure using the apps option.
Based on this I was then able to "build" the structure up from there.
In order to have the inheritance I was after this is what I ended up with:
#File: apps/crm/controllers/ClientsController.php
namespace myApp\CRM\Controllers
class ClientsController extends ControllerBase {...}
#File: apps/crm/controllers/ControllerBase.php
namespace myApp\CRM\Controllers
class ControllerBase extends \myApp\common\Controllers\FrontendBase {...}
#File: common/controllers/FrontendBase.php
namespace myApp\common\Controllers
class FrontendBase extends \myApp\common\Controllers\MasterBase {...}
#File: common/controllers/MasterBase.php
namespace myApp\common\Controllers
class MasterBase extends \Phalcon\Mvc\Controller {...}
Then in the file: apps/crm/Module.php I have the following:
namespace myApp\CRM;
class Module implements ModuleDefinitionInterface
{
public function registerAutoloaders()
{
$loader = new Loader();
$loader->registerNamespaces(array(
'myApp\CRM\Controllers' => __DIR__ . '/controllers',
'myApp\CRM\Models' => __DIR__ . '/models',
'myApp\common\Controllers' => __DIR__ . '/../../common/Controllers',
'myApp\common\Models' => __DIR__ . '/../../common/Models'
));
$loader->register();
}
}
This then works as you would expect. You can have functions in the MasterBase that you can call from the higher levels and you can also run functions such as adding css and JS to the output at the different levels, allowing you to separate out the control as you need.
I am currently using v1.12.2 Twig as a standalone templating engine.
I wrote a Twig extension called Utility_Twig_Extension in a file called UtilityExtension.php
and an index.php
//index.php
require_once '../vendor/twig/twig/lib/Twig/Autoloader.php';
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(OEBPS);
$twig = new Twig_Environment($loader, array(
'cache' => APP . DS . 'cache',
));
require_once '../vendor/twig/twig/ext/utility/UtilityExtension.php';
$twig->addExtension(new Utility_Twig_Extension());
Here is the UtilityExtension.php
//UtilityExtension.php
namespace UtilityTwigExtension;
class Utility_Twig_Extension extends Twig_Extension
{
public function getName()
{
return "utility";
}
}
Here is my directory structure:
src
|__app
| |__ index.php
|__vendor
|__twig
|__twig
|__ext
|__lib
I cannot even load the file properly.
I have traced the issue to the fact that the extension class tries to extend Twig_Extension.php.
So I require_once the Twig_Extension which is the Extension.php file in UtilityExtension.php. However, still not working.
Most documentation talks about adding a custom Twig Extension in the context of Symfony.
I am using Twig standalone, so I have yet to find any documentation on that.
Please advise.
UPDATE1:
By not working, I meant that I get the 500 server error. I ran error_reporting(E_ALL) was to no avail.
The error was relieved the moment I removed the words extends Twig_Extension from the extension class.
UPDATE2:
I realized it was a namespace issue. because I removed the namespace UtilityTwigExtension; from the UtilityExtension.php and the server 500 error was gone.
So I put the namespace UtilityTwigExtension; back and then call
require_once '../vendor/twig/twig/ext/utility/UtilityExtension.php';
$twig->addExtension(new UtilityTwigExtension\Utility_Twig_Extension());
the error came back.
Question: How do I call the TwigExtension if I insist on using the namespace? Is there a better way of using namespace?
UPDATE3:
I still get server 500 after trying Luceos answer.
error_reporting(E_ALL);
require_once 'constants.php';
require_once 'ZipLib.php';
require_once '../vendor/twig/twig/lib/Twig/Autoloader.php';
Twig_Autoloader::register();
$loader = new Twig_Loader_Filesystem(OEBPS);
$twig = new Twig_Environment($loader, array(
'cache' => APP . DS . 'cache',
));
require_once '../vendor/twig/twig/ext/utility/UtilityExtension.php';
use UtilityTwigExtension\Utility_Twig_Extension;
$twig->addExtension(new Utility_Twig_Extension());
the UtilityExtension.php
namespace UtilityTwigExtension;
class Utility_Twig_Extension extends Twig_Extension
{
/**
* Returns the name of the extension.
*
* #return string The extension name
*/
public function getName() {
return 'utility';
}
}
So let's put the comments in an answer and move on from there without crowding the comments:
First of call the extension from the correct namespace:
use UtilityTwigExtension\Utility_Twig_Extension;
$twig->addExtension(new Utility_Twig_Extension());
Use and namespaces calls are normally placed at the top of the file.
You can also try calling the namespace + object directly by using:
$twig->addExtension(new UtilityTwigExtension\Utility_Twig_Extension());
Update 3
The Utility_Twig_Extension extends Twig_Extension from the namespace UtilityTwigExtension, which does not exist. I assume Twig_Extension is not in any namespace so you'll use \Twig_Extension:
namespace UtilityTwigExtension;
class Utility_Twig_Extension extends \Twig_Extension
{
/**
* Returns the name of the extension.
*
* #return string The extension name
*/
public function getName() {
return 'utility';
}
}