Difference between revisions of "Update J3 component to J4"

From Joomla! Documentation

(Created page with "{{inprogressbyuser}} = Helpful Notes = Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component. These are the notes i wish I'd h...")
 
(Details of what I had to do to upgrade a J3 component to a J4)
Line 3: Line 3:
  
 
Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component.
 
Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component.
These are the notes i wish I'd had as I work through this project.  Hopefully they'll be helpful.  Feel free (in fact, feel obliged) to let me know if there are errors, ommission, or... errr... anything else that should cause a change.  I've been developing in Joomla for a long time, but I'm only just starting with J4.
+
These are the notes I wish I'd had as I work through this project.
 +
 
 +
My context is a primarily administrator screens only component.  Data structures are fairly complex, by comparison with core data at least. The component consists of about ten lists of structures, with view or edit forms behind thatThe installation file is currently just my own code and is around 130kB.  This will increase as there are still some functions to include, primarily providing end points of an associated mobile app.
 +
 
 +
In general, I found many things remain the same and the upgrade process isn't too hard, nor is there much that really got me scratching my head, once I'd worked out a couple of small pointsOf course, before I sorted it out, it was incredibly frustrating.
 +
 
 +
Feel free (in fact, feel obliged) to let me know, or simply edit, if there are errors, omissions, or anything else that can be helpfully changed.  I've been developing in Joomla for a long time, but I'm only just starting with J4.
  
 
= General Points =
 
= General Points =
It appears you can get away with making very minimal changes (eg see the MCE structure once it’s installed).  This guide tries to go the whole way, making the component fully compliant to J4 standards.
+
It appears you can get away with making very minimal changes (eg see the JCE installed structure).  I tried to go the whole way, making the component fully compliant to J4 standards.
  
 
Judging by the disparity between the documents I've found and what's actually in the released (core) code, it seems that things are still evolving, so a) it’s sometimes not clear what the current recommended usage is and b) this may become outdated as J4 evolves.
 
Judging by the disparity between the documents I've found and what's actually in the released (core) code, it seems that things are still evolving, so a) it’s sometimes not clear what the current recommended usage is and b) this may become outdated as J4 evolves.
Line 16: Line 22:
 
Namespacing is very central to the new philosophy.
 
Namespacing is very central to the new philosophy.
  
While it can be a little tedious, particularly during conversion,  this is really helpful and "A Good Thing"(TM).  If you need to know more details than I've got here, look at the docs.
+
While it can be a little tedious, particularly during conversion,  this is really helpful and "A Good Thing"<sup>TM</sup>.  If you need to know more details than I've got here, look at the docs.
  
 
Every file that declares a class should be namespaced.  Put very simply, it allows us to ensure the correct classes are loaded, even if there are several that have the same name.  We just specify the full path to pick the one we want.  With our own code, it means we can use the same names that are in other places and still get the right one.
 
Every file that declares a class should be namespaced.  Put very simply, it allows us to ensure the correct classes are loaded, even if there are several that have the same name.  We just specify the full path to pick the one we want.  With our own code, it means we can use the same names that are in other places and still get the right one.
Line 23: Line 29:
  
 
You can either write out its whole path at each point in the code that you use it, which makes for long code, or you can employ the “use” statement. At some point, normally at the top of your code, you write a use statement for the class you want and then whenever you refer to it you simply use the class name. For example to use the Factory class, at the head of your code include
 
You can either write out its whole path at each point in the code that you use it, which makes for long code, or you can employ the “use” statement. At some point, normally at the top of your code, you write a use statement for the class you want and then whenever you refer to it you simply use the class name. For example to use the Factory class, at the head of your code include
```use Joomla\CMS\Factory;```
+
<source lang="php">
 +
use Joomla\CMS\Factory;</source>
 
and then you can write Factory::{whatever-you-want} without needing to include the full path.
 
and then you can write Factory::{whatever-you-want} without needing to include the full path.
 
This is equivalent to the previous use of JLoader, but simpler.
 
This is equivalent to the previous use of JLoader, but simpler.
  
 
If you use two (or more) classes that have the same name but are from different namespaces, you can still use them by setting up aliases. For example
 
If you use two (or more) classes that have the same name but are from different namespaces, you can still use them by setting up aliases. For example
 +
<source lang="php">
 +
use Joomla\CMS\Factory as CoreFactory;
 +
use myCompany\Component\MyComponent\Administrator\Helper\MyFactory;</source>
  
 +
== They got rid of “J”! ==
  
 +
Lots of J3 core classes were called “J”-something, for example  “JFactory”. This is no longer true, this one thus becomes simply “Factory”.  This doesn’t (seem to) hold for core language string naming though.
  
 
+
== Flip it! ==
Get rid of “J”
 
Lots of J3 entities have been called “J”-something, for example  “Jfactory”. This is not longer the case.  The example given becomes simply “Factory”.  This doesn’t (seem to) hold for core language string naming though.
 
Flip it!
 
 
The previous rule for naming core entities often went (J){Type}{Client}, for example JcontrollerAdmin.
 
The previous rule for naming core entities often went (J){Type}{Client}, for example JcontrollerAdmin.
 
The new naming goes, according to the previous note remove the J, and then flip those elements, so we have AdminController.
 
The new naming goes, according to the previous note remove the J, and then flip those elements, so we have AdminController.
Filesystem
 
The new structure is (show it?)
 
Most src files are now {unit}{type}, where previously they were {mything}{type}{unit}eg what was MythingControllerMyunit is now MyunitController.
 
On case sensitive platforms (?), the case of file names needs to reflect the case of the class name. A spin off of this is that table classes and their files cannot  have upper case letters anywhere except the first letter, so you can’t have a table clase like CompoundTableNameTable, it has to be CompoundtablenameTable.
 
  
Controller
+
== Filesystem ==
 +
The new structure for an admin component is : (fill this in)
 +
 
 +
Most src files are now named {unit}{type}, where previously they were {mything}{type}{unit}.
 +
For example what was MythingControllerMyunit is now MyunitController.
 +
 
 +
On case sensitive platforms (?), the case of file names needs to reflect the case of the class name. A spin off of this is that table classes and their files cannot  have upper case letters anywhere except the first letter, so you can’t have a table class named CompoundTableNameTable, it has to be CompoundtablenameTable.
 +
 
 +
== Controller ==
 
getModel $prefix now needs to reflect the “client” for this controller, either “Administrator” or “Site”(?)
 
getModel $prefix now needs to reflect the “client” for this controller, either “Administrator” or “Site”(?)
 
Form controllers (as opposed to list controllers) now extend the core class FormController rather than JcontrollerAdmin.
 
Form controllers (as opposed to list controllers) now extend the core class FormController rather than JcontrollerAdmin.
 
Form controller same name as model helps => tables should be named in the singular (?)
 
Form controller same name as model helps => tables should be named in the singular (?)
  
Model
+
== Model ==
 
Form models now extend the AdminModel class.
 
Form models now extend the AdminModel class.
 
The getTable method is no longer required (or valid).
 
The getTable method is no longer required (or valid).
Line 55: Line 68:
 
Extending the core class “ListField” means that JformHelper::loadFieldClass('list'); is now redundant. (?)
 
Extending the core class “ListField” means that JformHelper::loadFieldClass('list'); is now redundant. (?)
  
View
+
== View ==
Class naming
+
=== Class naming ===
 
Previous setup {UnitRef}{fill this in}.  It’s now HtmlView!
 
Previous setup {UnitRef}{fill this in}.  It’s now HtmlView!
 
Convert the previous “JerrorRaiseError(500, implode('<br />', $errors); return false” to  
 
Convert the previous “JerrorRaiseError(500, implode('<br />', $errors); return false” to  
 
throw new GenericDataException(implode("\n", $errors), 500);
 
throw new GenericDataException(implode("\n", $errors), 500);
 
(There’s that ol’ “switcheroo” thang again.)
 
(There’s that ol’ “switcheroo” thang again.)
The sidebar thing is gone.
+
=== The sidebar thing is gone ===
 
Toolbar structure is now different.  The ToolbarHelper still exists, without its previous J prefix of course, but it’s used for many fewer things, typically now just the title. Create a toolbar (actually get an instance of it) and use its methods to set it up.  There are specific methods now rather than passing multiple parameters to the helper.
 
Toolbar structure is now different.  The ToolbarHelper still exists, without its previous J prefix of course, but it’s used for many fewer things, typically now just the title. Create a toolbar (actually get an instance of it) and use its methods to set it up.  There are specific methods now rather than passing multiple parameters to the helper.
 
Creating your own toolbar buttons is now “regular” not “custom”.
 
Creating your own toolbar buttons is now “regular” not “custom”.
 
Creating a modal is now a popupButton and not in “customButton”
 
Creating a modal is now a popupButton and not in “customButton”
  
Templates
+
== Templates ==
 
New filesystem position – to facilitate moving code away from the webserver root in future.
 
New filesystem position – to facilitate moving code away from the webserver root in future.
  
Changes due to new style / standard
+
= Changes due to new style / standard =
General
+
== General ==
 
Remove the message that goes with the ubiquitous “defined('_JEXEC') or die()”
 
Remove the message that goes with the ubiquitous “defined('_JEXEC') or die()”
  
Debugging notes
+
= Debugging notes =
 
The error “Call to a member function getGroup() on null” may mean the xml filter definition file is not present.
 
The error “Call to a member function getGroup() on null” may mean the xml filter definition file is not present.
 
Custom field types don’t work?  Need to add the namespace prefix in the form definition file.
 
Custom field types don’t work?  Need to add the namespace prefix in the form definition file.
  
 
Specific changes
 
Specific changes
Core classes to overload
+
 
Type
+
{| class="wikitable"
Old
+
|+ Core classes to overload
New
+
|-
List controller
+
! Type !! Old !! New
JControllerAdmin
+
|-
AdminController
+
| List controller || JControllerAdmin || AdminController
List mode
+
|-
JmodelAdmin
+
| List model || JmodelAdmin || ListModel
ListModel
+
|-
List view (html)
+
| List view (html) || JViewLegacy (?) || HtmlView
JViewLegacy (?)
+
|-
HtmlView
+
| Form controller || JControllerForm || FormController
Form controller
+
|-
JControllerForm
+
| Form model || JModelAdmin || FormModel
FormController
+
|-
Form model
+
| Form view (html) || JViewLegacy (?) || HtmlView
JModelAdmin
+
|}
FormModel
+
{{JVer|4.0}}
Form view (html)
 
JViewLegacy (?)
 
HtmlView
 

Revision as of 10:53, 6 May 2022

Helpful Notes[edit]

Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component. These are the notes I wish I'd had as I work through this project.

My context is a primarily administrator screens only component. Data structures are fairly complex, by comparison with core data at least. The component consists of about ten lists of structures, with view or edit forms behind that. The installation file is currently just my own code and is around 130kB. This will increase as there are still some functions to include, primarily providing end points of an associated mobile app.

In general, I found many things remain the same and the upgrade process isn't too hard, nor is there much that really got me scratching my head, once I'd worked out a couple of small points. Of course, before I sorted it out, it was incredibly frustrating.

Feel free (in fact, feel obliged) to let me know, or simply edit, if there are errors, omissions, or anything else that can be helpfully changed. I've been developing in Joomla for a long time, but I'm only just starting with J4.

General Points[edit]

It appears you can get away with making very minimal changes (eg see the JCE installed structure). I tried to go the whole way, making the component fully compliant to J4 standards.

Judging by the disparity between the documents I've found and what's actually in the released (core) code, it seems that things are still evolving, so a) it’s sometimes not clear what the current recommended usage is and b) this may become outdated as J4 evolves.

Again, let me know if something is (perhaps "no longer") correct.

Namespacing[edit]

Namespacing is very central to the new philosophy.

While it can be a little tedious, particularly during conversion, this is really helpful and "A Good Thing"TM. If you need to know more details than I've got here, look at the docs.

Every file that declares a class should be namespaced. Put very simply, it allows us to ensure the correct classes are loaded, even if there are several that have the same name. We just specify the full path to pick the one we want. With our own code, it means we can use the same names that are in other places and still get the right one.

Allowing the same names to be used in different contexts means that you have to specify the name space that you want. That then means that whenever you want to use classes in your code that aren’t in the current namespace, you have to use its full name.

You can either write out its whole path at each point in the code that you use it, which makes for long code, or you can employ the “use” statement. At some point, normally at the top of your code, you write a use statement for the class you want and then whenever you refer to it you simply use the class name. For example to use the Factory class, at the head of your code include

use Joomla\CMS\Factory;

and then you can write Factory::{whatever-you-want} without needing to include the full path. This is equivalent to the previous use of JLoader, but simpler.

If you use two (or more) classes that have the same name but are from different namespaces, you can still use them by setting up aliases. For example

use Joomla\CMS\Factory as CoreFactory;
use myCompany\Component\MyComponent\Administrator\Helper\MyFactory;

They got rid of “J”![edit]

Lots of J3 core classes were called “J”-something, for example “JFactory”. This is no longer true, this one thus becomes simply “Factory”. This doesn’t (seem to) hold for core language string naming though.

Flip it![edit]

The previous rule for naming core entities often went (J){Type}{Client}, for example JcontrollerAdmin. The new naming goes, according to the previous note remove the J, and then flip those elements, so we have AdminController.

Filesystem[edit]

The new structure for an admin component is : (fill this in)

Most src files are now named {unit}{type}, where previously they were {mything}{type}{unit}. For example what was MythingControllerMyunit is now MyunitController.

On case sensitive platforms (?), the case of file names needs to reflect the case of the class name. A spin off of this is that table classes and their files cannot have upper case letters anywhere except the first letter, so you can’t have a table class named CompoundTableNameTable, it has to be CompoundtablenameTable.

Controller[edit]

getModel $prefix now needs to reflect the “client” for this controller, either “Administrator” or “Site”(?) Form controllers (as opposed to list controllers) now extend the core class FormController rather than JcontrollerAdmin. Form controller same name as model helps => tables should be named in the singular (?)

Model[edit]

Form models now extend the AdminModel class. The getTable method is no longer required (or valid).

Field (code implementing form field types used (eg) in form xml definitions) Class naming is brought in line with other classes, ie it doesn’t need to be preceded by “JformField”, simply followed by “Field”. Ie the old JformFieldMyType becomes MyTypeField. Extending the core class “ListField” means that JformHelper::loadFieldClass('list'); is now redundant. (?)

View[edit]

Class naming[edit]

Previous setup {UnitRef}{fill this in}. It’s now HtmlView! Convert the previous “JerrorRaiseError(500, implode('
', $errors); return false” to throw new GenericDataException(implode("\n", $errors), 500); (There’s that ol’ “switcheroo” thang again.)

The sidebar thing is gone[edit]

Toolbar structure is now different. The ToolbarHelper still exists, without its previous J prefix of course, but it’s used for many fewer things, typically now just the title. Create a toolbar (actually get an instance of it) and use its methods to set it up. There are specific methods now rather than passing multiple parameters to the helper. Creating your own toolbar buttons is now “regular” not “custom”. Creating a modal is now a popupButton and not in “customButton”

Templates[edit]

New filesystem position – to facilitate moving code away from the webserver root in future.

Changes due to new style / standard[edit]

General[edit]

Remove the message that goes with the ubiquitous “defined('_JEXEC') or die()”

Debugging notes[edit]

The error “Call to a member function getGroup() on null” may mean the xml filter definition file is not present. Custom field types don’t work? Need to add the namespace prefix in the form definition file.

Specific changes

Core classes to overload
Type Old New
List controller JControllerAdmin AdminController
List model JmodelAdmin ListModel
List view (html) JViewLegacy (?) HtmlView
Form controller JControllerForm FormController
Form model JModelAdmin FormModel
Form view (html) JViewLegacy (?) HtmlView

Joomla 4.0