Gadgetto Posted December 9, 2018 Share Posted December 9, 2018 I followed some sample modules to start my first project. The module installs/uninstalls fine but when I click the module's page I get the following error: Fatal Error: Uncaught TypeError: Argument 1 passed to ProcessWire\ProcessController::getProcessMethodName() must be an instance of ProcessWire\Process, instance of ProcessWire\GoodNews given, called in /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php on line 324 and defined in /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php:260 Stack trace: #0 /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php(324): ProcessWire\ProcessController->getProcessMethodName(Object(ProcessWire\GoodNews)) #1 /Users/mgartner/ProjekteWEB/processwire/wire/core/Wire.php(380): ProcessWire\ProcessController->___execute() #2 /Users/mgartner/ProjekteWEB/processwire/wire/core/WireHooks.php(723): ProcessWire\Wire->_callMethod('___execute', Array) #3 /Users/mgartner/ProjekteWEB/processwire/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\ProcessController), 'execute', Array) #4 /Users/mgartner/ProjekteWEB/processwire/wire/core/admin.php(135): ProcessWire\Wire->__ca (line 260 of /Users/mgartner/ProjekteWEB/processwire/wire/core/ProcessController.php) This error message was shown because: you are logged in as a Superuser. Error has been logged. Here is the full source: <?php namespace ProcessWire; /** * GoodNews module * * An integrated group and newsletter mailing system for Processwire. * * This file is licensed under the MIT license * https://processwire.com/about/license/mit/ * * ProcessWire 3.x, Copyright 2016 by Ryan Cramer * https://processwire.com * */ class GoodNews extends WireData implements Module { const debug = false; const pageName = 'goodnews'; const minVersionPHP = '5.6.37'; /** * Required by all modules to tell ProcessWire about them * * @return array */ public static function getModuleinfo() { return array( // The module's title, typically a little more descriptive than the class name 'title' => 'GoodNews', // A brief description of what this module is 'summary' => 'An integrated group and newsletter mailing system.', // Module version number: use 1 for 0.0.1 or 100 for 1.0.0, and so on 'version' => 1, // Name of module author 'author' => 'Martin Gartner, bitego', // Optional URL to more information about the module 'href' => 'http://modules.processwire.com/goodnews', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. //'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). //'autoload' => true, // For more options that you may specify here, see the file: /wire/core/Process.php // and the file: /wire/core/Module.php ); } public function execute() { if (version_compare(PHP_VERSION, self::minVersionPHP) >= 0) { // good } else { $this->error("Please note that your current PHP version (" . PHP_VERSION . ") is not adequate to run this module."); } $out = 'Test'; return $out; } /** * Executed on install */ public function ___install() { // Create the page the module will be assigned to $page = new Page(); $page->template = 'admin'; $page->name = self::pageName; // Installs to the admin main menu $page->parent = $this->pages->get($this->config->adminRootPageID); //->child('name=setup'); $page->process = $this; // Page title is the same as our module title $info = self::getModuleInfo(); $page->title = $info['title']; // Save the page $page->save(); // Tell the user we created this page $this->message("Created Page: {$page->path}"); } /** * Executed on uninstall */ public function ___uninstall() { // Find the page we installed, locating it by the process field (which has the module ID) // It would probably be sufficient just to locate by name, but this is just to be extra sure. $moduleID = $this->modules->getModuleID($this); $page = $this->pages->get("template=admin, process=$moduleID, name=" . self::pageName); if($page->id) { // If we found the page, let the user know and delete it $this->message("Deleting Page: {$page->path}"); $page->delete(); } } } Any hints? Thanks, Martin Link to comment Share on other sites More sharing options...
horst Posted December 9, 2018 Share Posted December 9, 2018 (edited) I think you are mixing ProcessModules with Other modules. The class skeleton of a process module has to look like this: class ProcessGoodNews extends Process implements Module { ... First add the prefix "Process" to your modules classname and also to the filename, and second you have to extend Process and not WireData. PS: the title can stay as is, Good News, or GoodNews, but the class name and filename should be prefixed with Process. PPS: I think you also have to prefix the execute() function name by three underscores: ___execute() < Thats wrong, as @teppo mentioned below. Sorry. PPPS: maybe some interesting reads about ProcessModules and different possibilities:https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/https://processwire.com/blog/posts/new-module-configuration-options/https://processwire.com/talk/topic/13618-does-using-dedicated-module-files-help-a-lazy-programmer/ Edited December 9, 2018 by horst add another hint and links 4 Link to comment Share on other sites More sharing options...
Robin S Posted December 9, 2018 Share Posted December 9, 2018 Also take a look at Ryan's helpful ProcessHello demo module: https://github.com/ryancramerdesign/ProcessHello It's a lot simpler to use getModuleInfo() (or its equivalent if using the other module configuration options Horst linked to above) to specify the page used by the Process module because then it will be automatically created on module install and removed on module uninstall. See the ProcessHello example: https://github.com/ryancramerdesign/ProcessHello/blob/9c1aa18eb40d069c7fb227f09badddc90f0b3276/ProcessHello.info.php#L41-L46 3 Link to comment Share on other sites More sharing options...
teppo Posted December 9, 2018 Share Posted December 9, 2018 31 minutes ago, horst said: PPS: I think you also have to prefix the execute() function name by three underscores: ___execute() That isn't actually necessary; Process module execute methods don't have to be hookable. (Gadgetto, in case you haven't yet looked into the hook system, three underscores are only required if you want to make the function hookable – i.e. allow code in template files, modules, init.php / ready.php files within site directory, etc. to "hook" into their execution. Otherwise it's fine to leave them out.) On a loosely related note, you also don't have to set up your own PHP version comparison. You can define required PHP version with the "requires" setting ? 3 Link to comment Share on other sites More sharing options...
Gadgetto Posted December 10, 2018 Author Share Posted December 10, 2018 Below is part of the source from the pre-installed Helloworld module which comes with Processwire 3.x: It has no prefixed class name and no prefixed file name. It also extends WireData and implements Module. I built my module exactly like this but it won't work. <?php namespace ProcessWire; /** * ProcessWire 'Hello world' demonstration module * * Demonstrates the Module interface and how to add hooks. * * See README file for further links regarding module development. * * This file is licensed under the MIT license * https://processwire.com/about/license/mit/ * * ProcessWire 3.x, Copyright 2016 by Ryan Cramer * https://processwire.com * */ class Helloworld extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( // The module's title, typically a little more descriptive than the class name 'title' => 'Hello World', // version number 'version' => 3, // summary is brief description of what this module is 'summary' => 'An example module used for demonstration purposes.', // Optional URL to more information about the module 'href' => 'https://processwire.com', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. 'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). 'autoload' => true, // Optional font-awesome icon name, minus the 'fa-' part 'icon' => 'smile-o', ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { // add a hook after the $pages->save, to issue a notice every time a page is saved $this->pages->addHookAfter('save', $this, 'example1'); // add a hook after each page is rendered and modify the output $this->addHookAfter('Page::render', $this, 'example2'); // add a 'hello' method to every page that returns "Hello World" // use "echo $page->hello();" in your template file to display output $this->addHook('Page::hello', $this, 'example3'); // add a 'hello_world' property to every page that returns "Hello [user]" // use "echo $page->hello_world;" in your template file to display output $this->addHookProperty('Page::hello_world', $this, 'example4'); } ..... ... . } Link to comment Share on other sites More sharing options...
bernhard Posted December 10, 2018 Share Posted December 10, 2018 14 hours ago, horst said: I think you are mixing ProcessModules with Other modules. Agree @Gadgetto what is your goal? What do you want to build? If we knew that it would be easier to help you. You have 3 main options to customize ProcessWire: Hooks in ready.php Very easy, but can get hard to maintain if you have lots of customizationshttps://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks Regular modules You can include your own scripts, libraries, hooks etc. You can modify almost anything you want - for example inject custom scripts, modify rendering of fields in the admin, sending emails on special events in the frontend etc...https://github.com/ryancramerdesign/Helloworld Process modules They are used to build custom admin pages in the backend. See my forum + blog post to get a quick introduction.https://github.com/ryancramerdesign/ProcessHello 1 Link to comment Share on other sites More sharing options...
Gadgetto Posted December 10, 2018 Author Share Posted December 10, 2018 Is there an overview in which case a module should use which class and which implementation model? Samples: class ProcessWireUpgrade extends Process { // extends Process class Helloworld extends WireData implements Module { // extends WireDate class CustomAdminPage extends Process { // without prefix "Process" class ProcessCustomAdminPage extends Process { // prefixed with "Process" Link to comment Share on other sites More sharing options...
Gadgetto Posted December 10, 2018 Author Share Posted December 10, 2018 6 minutes ago, bernhard said: Agree @Gadgetto what is your goal? What do you want to build? If we knew that it would be easier to help you. You have 3 main options to customize ProcessWire: Hooks in ready.php Very easy, but can get hard to maintain if you have lots of customizationshttps://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks Regular modules You can include your own scripts, libraries, hooks etc. You can modify almost anything you want - for example inject custom scripts, modify rendering of fields in the admin, sending emails on special events in the frontend etc...https://github.com/ryancramerdesign/Helloworld Process modules They are used to build custom admin pages in the backend. See my forum + blog post to get a quick introduction.https://github.com/ryancramerdesign/ProcessHello Hello @bernhard ragarding my other post: I'm starting the port of my MODX add-on GoodNews - a integrated group and newsletter mailing system - to Processwire. The add-on will be a full featured app which willl have custom admin pages, modules for sending mails, and so on ... As I'm just scratching the surface of Processwire, I can't say which module types I will need. Link to comment Share on other sites More sharing options...
Gadgetto Posted December 11, 2018 Author Share Posted December 11, 2018 I have now tried to get more information about different module types and when to use what. So, I try to port my MODX add-on - a complete newsletter system with subscriber management and registration. As far as I understand, ProcessWire has "Regular" modules and "Process" modules. Process modules, if I understand correctly, are used to create custom admin areas in the backend. "Regular" modules for all other things, like output in frontend, hooks, services, mail dispatch etc. Therefore I will probably need several different modules to implement my project: 1) Process module for the admin part of the newsletter add-ons (newsletter creation, mailing, subscriber management etc.) 2) Regular modules for mail handling / sending engine etc. 3) Regular modules for subscription forms and user profile editing by subscribers Am I right about that? @bernhard, @teppo, @horst Link to comment Share on other sites More sharing options...
bernhard Posted December 11, 2018 Share Posted December 11, 2018 4 minutes ago, Gadgetto said: Regular modules for subscription forms and user profile editing by subscribers 1 + 2 yes, but this one sounds strange. But it depends a lot on how you plan everything. I'd start with a simpler module first to get familiar with module development. This one would be a nice project to start with: You'd have some user input (teaser: image uploads can be tricky), some methods to generate markup, http requests via the API, but not all the complexity that you have in your full blown module. I'd always be available for help on the road ? 1 Link to comment Share on other sites More sharing options...
Gadgetto Posted December 11, 2018 Author Share Posted December 11, 2018 Thanks a lot, @bernhard I'll have a look at your hints + I'll for sure come back with more questions. ? As I wrote my GoodNews add-on for MODX I also jumped into cold water and started development immediately. The problem is not so much in the API as in how to do things in ProcessWire. Link to comment Share on other sites More sharing options...
Soma Posted December 11, 2018 Share Posted December 11, 2018 15 minutes ago, Gadgetto said: Thanks a lot, @bernhard I'll have a look at your hints + I'll for sure come back with more questions. ? As I wrote my GoodNews add-on for MODX I also jumped into cold water and started development immediately. The problem is not so much in the API as in how to do things in ProcessWire. That's exactly the point. You might regret it. Doing such a complex project without experience is never a good idea. 3 Link to comment Share on other sites More sharing options...
kongondo Posted December 12, 2018 Share Posted December 12, 2018 On 12/11/2018 at 4:05 PM, Gadgetto said: As far as I understand, ProcessWire has "Regular" modules and "Process" modules. Not really, 'regular'. Have a look at this post. It is old but still relevant (see module prefixes): 1 Link to comment Share on other sites More sharing options...
Paul Greinke Posted April 5, 2022 Share Posted April 5, 2022 I stumbled across this post searching for the reason why my module won't create the process page under setup. I tried some suggestions from this threat, but eventually found another solution. I just wanted to share this in case someone needed it. I used the getModuleInfo() function to add a page. I did not prefix my modules name with "Process" but only extended it with the Progress class. The only thing I had to do was calling the parents install() method in my modules install() method. That`s it. Now the setup page is created automatically on install. <?php namespace ProcessWire; class MyModule extends Process implements ConfigurableModule { public static function getModuleInfo() { return [ 'title' => 'My Module', 'summary' => 'A module', 'version' => 1, 'page' => array( 'name' => 'mymodule', 'parent' => 'setup', 'title' => 'My Module', ) ]; } public function install() { parent::___install(); } public function uninstall() { parent::___uninstall(); } } 2 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now