I'm making a custom contact form in Craft CMS with a module. The goal is to view all submitted forms in the dashboard and have the possibility to mail after submissions. Submitting the form results in a HTTP 404 – Not Found error.
I made the module, controller and action needed for this. I configured the module in app.php of the config folder and added it to psr-4 in composer.json to autoload it. I know namespacing and routing is a common issue, so I tried a lot of possible combinations.
This is what the folder structure looks like:
modules/
├─ submissions/
├─ Module.php
├─ Controllers/
├─ defaultController.php
The action input of the form looks like this:
{{ actionInput('submissions/default/send-submission') }}
The module looks like this:
<?php
namespace submissions;
use Craft;
class Module extends \yii\base\Module
{
public function init()
{
// Define a custom alias named after the namespace
Craft::setAlias('#submissions', __DIR__);
// Set the controllerNamespace based on whether this is a console or web request
if (Craft::$app->getRequest()->getIsConsoleRequest()) {
$this->controllerNamespace = 'modules\\submissions\\console\\controllers';
} else {
$this->controllerNamespace = 'modules\\submissions\\controllers';
}
parent::init();
}
}
The controller looks like this:
<?php
namespace modules\submissions\controllers;
use Craft;
class defaultController extends Controller
{
protected $allowAnonymous = [
'action' => self::ALLOW_ANONYMOUS_LIVE | self::ALLOW_ANONYMOUS_OFFLINE,
];
public function actionSendSubmission()
{
echo "test";
}
}
Using an actionUrl also results in the same error:
link
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
Hi I'm pretty new to MVC framework. I decided to build a small application in MVC to get better understanding.
I googled around and found PIP framework that i can use for simple application and then modify once i will get complete understanding.
PIP can be found here
Now i have one question that by looking to PIP framework, do i need to design to new controller for every page that i will use.
For e.g
applications/
views/
home.php
about.php
contact.php
controllers/
main.php
aboutus.php ??
contactus.php ??
For eg. my default controller and view is main.php and home.php and i have a controller for main.php as below:
<?php
class Main extends Controller {
function index()
{
$template = $this->loadView('home');
$template->set('title', "Welcome Homepage");
$template->render();
}
}
?>
So, in this way, do i need to create new conrollers for about and contact.php
PIP's routing is internalized and requires a specific scaffolding of your controllers:
When you go to:
example.com/main
It looks for the controller main and then the function index by default.
If you were going to have 1 controller per view, then it would be something like:
example.com/main
class Main extends Controller
example.com/about
class About extends Controller
example.com/contact
class Contact extends Controller
However, if you went with a default page controller, this would greatly simplify the scaffolding:
example.com/page/{about|contact|main}
class Page extends Controller {
public function about (){
}
public function contact(){
}
public function main(){
}
}
Now 1 controller will handle the delivery of each of these pages.
With pip the URL defines the controller and function that will be executed. If you want the contact page to be at mysite.com/contact, you do need to add a Contact controller.
You do not need to create a new controller for every page. Lets assume you had a forum. You could have the following urls:
mysite.com/blog/write
mysite.com/blog/view/15
These different URLs would all be handled in one controller, blog.php
<?php
class Blog extends Controller {
public function write()
{
echo 'Hello World!';
}
public function view($postId)
{
echo 'Viewing post: ' . $postId;
}
}
I also used PIP as a starter framework, and extended it to include some additional functionality. I even started to document my efforts, but other projects have taken me in other directions.
Happy to share what I have, and some documentation on my PIP efforts can be found at http://www.shed22.com/pip.
Let me know if you would like a copy of the source code and a sample application.
Stephen
How to call function from another controller in Phalcon PHP framework. Here is example for CakePHP http://sherwinrobles.blogspot.com/2013/02/cakephp-calling-function-from-other.html
Based on the link you provided, to my knowledge there is no direct way to call a function in another controller using the request object. However instantiating the controller and calling the function will work just it does in CakePHP
$newController = new \MyNS\Controllers\NewController();
$newController->myFunc();
If you want you can use a static function inside the controller and call it
\MyNS\Controllers\NewController::myFunc();
This is already Tested
For the people that aren't using CakePHP
another way to do this would be to do a helper Folder and write actions, in this case methods.
public/index.php
Add the path helper
$loader->registerDirs(
[
APP_PATH . '/helper/'
]
);
Add a helper Order in apps
└── apps
├── controllers
└─ exampleController.php
├── models
└── helpers
└─ myHelper.php
...
In myHelper.php
<?php
use Phalcon\Di\Injectable;
class myHelper extends Injectable
{
function myNameFunction() {
// here you should write your function
}
}
In exampleController where you want to call the other action, in this case function
<?php
use Phalcon\Mvc\Controller;
class exampleController extends Controller {
public function yourAction() {
//your code
//there are 2 ways of calling the function. either use this one
$myHelper = new myHelper();
$myHelper->myNameFunction();
//or this one
(new UnmatchHelper())->myNameFunction();
}
}
I am using the modular extensions HMVC add on for codeigniter.
my structure looks as follows:
modules/
-manager/
--controllers/
---manager.php
--views/
---index.php
the manager.php controller:
class Manager extends MX_Controller {
function __construct(){
parent::__construct();
}
function index(){
$data['newsletter'] = Newsletter::all();
$this->load->view('index',$data);
}
}
Routing and printing from inside the controller itself works fine, but I can't seem to load a view, get a codeigniter error saying the view file can't be found
/modules/manager/config/routes.php:
<?php
$route['module_name'] = 'manager';
It seems the views are still being called from CI's main view folder, not sure why they are not calling from the modules folder because the controller is extending the MX class
Try this:
$this->load->view('manager/index',$data);
Structure for folders:
apllication
modules
manager
config
routes.php
controllers
manager.php
views
index.php
I've the next structure
-application
--controllers
---Sub
----DemoController.php
---IndexController.php
-models
-views
-Boostrap.php
Well, in my Sub/DemoController.php I've the next:
<?php
class Sub_DemoController extends Zend_Controller_Action
{
public function indexAction()
{
echo 'hello demo';
}
}
And my IndexController.php like this:
<?php
class IndexController extends Sub_DemoController
{
}
When I run my web throw the next error: Class 'Sub_DemoController' not found ...
I try with initialize class with Application_Sub_DemoController, but return the same result.
I don't want use modules, I know how uses modules in Zend Framewoork but I don't looking for it.
Any ideas?
You need to add resourceType to your resource autoloader add this to you bootstrap file:
$this->getResourceLoader()
->addResourceType('sub', 'controllers/Sub', 'Sub');
More: http://framework.zend.com/manual/1.12/en/zend.loader.autoloader-resource.html
Please have a look at Zend framework (1.7.5): how to change controller directory
I think you didn't set the controller directory properly or your autoloader does not work.