Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions docs/building-extensions/development/checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---
title: Step-by-step list to setup a development environment for an existing extension
---

Step-by-step list to setup a development environment for an existing extension
=================

1. Create a folder for your repository
2. Create a project on Github or your git manager of choice
3. Clone the git repository into your folder or initialise a new git repository with `git init`
4. Run `composer require --dev joomla-projects/jorobo` in the folder
5. Run `vendor/bin/jorobo init` in the folder and say `yes` to use all features. You now have `php-cs-fixer`, `phpcs` for codestyle, `phpstan` for static codeanalysis, `phpunit` for unittests, `JoRobo` for release packaging and some additional tasks, `.gitignore` and `.editorconfig` for your IDE configured, as well as a `/src` folder for your source code.
6. Run `vendor/bin/jorobo ci` in the folder and select if you want to insert a setup for a Github Actions or Gitlab CI setup.
7. Modify your `jorobo.dist.ini` for your project
8. Commit all of this for your initial commit to your project.
9. Copy your unzipped extension into your `/src` folder and commit those files. Now you can go back to this first commit in case you messed something up.
10. Create a `/joomla` folder and add a copy of the Joomla version you want to support in it. This is used by the IDE, phpstan and rector to understand what the Joomla core classes are doing. This folder is already part of your `.gitignore` file.
11. Run `vendor/bin/php-cs-fixer fix` in the root of the project to get all your files to adhere to the PSR-12/PHP PER coding style. Commit the changes, create a `.git-blame-ignore-revs` and add the hash of the commit as one line in the file. This helps when using `blame` in git later when trying to find out who did what changes when.
12. Run `vendor/bin/jorobo rector` to install Rector to refactor your code automatically. It will create a default `rector.php` in the root of your project, which you have to modify. Please read the [documentation here](https://github.com/joomla-projects/jrector/blob/main/docs/index.md) to understand what you are doing! Run rector with `vendor/bin/rector --dry-run` to check the changes first and then without the parameter to actually do the modifications. After each run, check the modifications and commit them.

If you have a non-namespaced extension, the following steps will help you with updating it to namespaces:
- The MVC rules creates a `rename.php`, which moves the files to their new places in the namespaced structure. Since rector decided against doing filesystem operations, this needs to be run separately by calling `php rename.php` in the root of your project. Remember to commit before and after moving the files, so that git keeps the connection between the old and new location and you retain the history across the move of the files.
- Now add the namespace to your extensions manifest file by adding `<namespace path="src">Your\Base\Namespace\Component\Componentname</namespace>` to it.
- You are now still missing the `services/provider.php` in your components administrator folder. This you have to create manually.
13. Commit the changes to your repository and push them to your Github or Gitlab. Run `vendor/bin/php-cs-fixer fix` once more for good measure to ensure the changes by rector did not introduce new codestyle issues.
14. If your folder structure of your old extension does not follow the structure when installed in a Joomla installation, you should now move the admin part to `src/administrator/components/<your component>`, your site part to `src/components/<your component>` etc. Remember to commit that change.
15. Now would be the time that you really should open your project in PHPStorm if you haven't done so already.
16. Create a test installation of Joomla somewhere to test your extension.
17. Copy the content of your `/src` folder over the test installation to have all current project files in the right locations at this point.
18. Now we want to automatically copy all changes in our repository to the test installation. Go to `Settings -> Build, Execution, Deployment -> Deployment` and create a new deployment target with your test installation as target. Also set the `Mappings` and mark the deployment target as default. Go to `Settings -> Build, Execution, Deployment -> Deployment -> Options` and set `Upload changed files automatically to the default server` to `Always`. Now all modifications in PHPStorm will automatically show up in your test installation.
19. Now run `vendor/bin/phpstan` to get a report of all issues phpstan is finding. Fix them, commit, repeat until you are happy with the number of errors.
20. Discover your extension and test it in your test installation, fix all bugs you notice, commit after each bug, repeat until you are happy with the current state.
21. Run `vendor/bin/robo headers` to update all your copyright headers to the right structure you can defined in your `jorobo.dist.ini`. Pay attention that you are only changing the headers of your own code and not from third parties! Commit!
22. Modify your manifest file and replace the relevant parts with the placeholders from JoRobo defined in the documentation here.
23. Set the version in your manifest and wherever else you need to set it, create a new tag and then run `vendor/bin/robo build`. You now have your installable extension package in your projects `/dist` folder.

Congratulations, you now updated your Joomla 3 or later extension to the latest Joomla version, applied the standard codestyle for PHP projects, updated your code to PHP 8.1, don't have any deprecated code and now have a professional development environment including a CI system for each commit.

New contributors to your extension only have to check out the repository and run `composer i` in the root of the project to have a working setup. Additonally you could create unit tests or add a system test setup with cypress to ensure your extension still works as expected after each change you do in the future.

While all of these checks aren't a guarantee that your code is bug-free, it should greatly help increasing the quality of your extension and give you the opportunity to concentrate on providing new value with improved features to your users.
22 changes: 22 additions & 0 deletions docs/building-extensions/development/checks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Next one in the series: How to automatically check your extensions code. There are of course several different ways to check your code with static analysers. I'm just going to explain how I'm doing it with phpstan right now. phpstan can easily be installed via composer with `composer require --dev phpstan/phpstan` in the root of your site or your repo. You can then call it with `vendor/bin/phpstan` (or `vendor\bin\phpstan` for Windows) on the CLI in the respective root. If you are developing an extension in a git repo, I would advise to have all your code in a subfolder like `/src`, so that you can keep all the dev tools, configurations and documentation in the root (or folders below the root) of your repo. If you are checking the extension inside a site installation, you can still do that, but it requires a bit more work. Besides the initial `phpstan/phpstan` package, I would advise to also install `phpstan/phpstan-deprecation-rules` (with `composer require --dev phpstan/phpstan-deprecation-rules`) as well to get all deprecated code.

phpstan can either be called with command line options or you can use a configuration file. I strongly recommend the later option and for the git repo solution described above, your config file could look like this:
```
includes:
- vendor/phpstan/phpstan-deprecation-rules/rules.neon
parameters:
level: 0
paths:
- src
scanDirectories:
- joomla
ignoreErrors:
reportUnmatchedIgnoredErrors: false
```
What does this do? First of all, it include the deprecation rules. Then it defines the strictness level, which currently is set to its lowest. You can raise that step by step and ideally you should reach level 5 at some point. It then defines the paths to check. If you follow the structure that I proposed above for a git repo, you only have to define the single `/src` folder here. If you are checking an extension installed inside a site, you would have to list all paths here, like `components/com_test` and `administrator/components/com_test`. Of course you only need those folders, which contain PHP code. The next config option is then the information which additional folders to read for framework information. phpstan automatically reads the `/vendor` folder and with this option you can add additional code to this. In the above example, I copied a complete Joomla package into a subfolder `/joomla` of the repo and phpstan now can understand all references to classes in your code to that Joomla package. That way, you are teaching phpstan what all the Joomla core classes mean and do. At least in theory, because Joomla itself often enough is still struggling to provide code which a tool like phpstan can understand.

Now you can call `vendor/bin/phpstan` on your code and will get a list of all things phpstan doesn't understand, considers wrong or reads as deprecated. Now comes the fun part of going through that code to fix stuff or make phpstan better understand it. Now don't dismiss the part about making phpstan understanding your code better, because it isn't just phpstan which will better understand your code, but also both you and your IDE. It is quite a difference when all of a sudden you notice that the object you got from a function call actually already contains the code you need instead of having to re-invent this.

From my experience, there are 4 methods on how to improve your code. The first one is of course to prevent magic code, which might return different stuff with different text input. All those `$items = $this->get('Items');` in the views are horrible for this, because no analyser can find out what `$this->get()` actually returns. Avoid stuff like this where possible! The second method is to typehint variables. If instead of `$items = $this->get('Items');`, you use `$model = $this->getModel();$items = $model->getItems();`, you can now typehint that `$model` is a `Testeroo\Component\Site\Model\TestModel` class by adding `/** @var Testeroo\Component\Site\Model\TestModel $model */` somewhere in the file (preferably directly above the line where you are assigning `$model`). The third method is typehinting return method parameters and return values in your code directly. If your method shouldn't return anything, mark it as returning `void`. Which leads me to the fourth method and that comes into action when the typehinting capabilities of PHP are too limiting. In that case, you define those types in the docblocks.

Adding phpstan to your project is easy and a matter of minutes, while I also was able to find a lot of bugs that way. Please give it a try.
Empty file.
Empty file.
45 changes: 45 additions & 0 deletions docs/building-extensions/development/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
---
title: Sustainable Extension Development Setup
---

Sustainable Extension Development Setup
=================

Unless you are writing a trivial extension and you are doing it just for a one-time quick test, you eventually run into the question how to make development easier, sustainable and professionell.
This section of the manual documents one way to setup a professional development setup, which allows you to do reliable coding, have a build script for your extensions and ensure quality with several tools.

While this tutorial provides a full setup, you *don't* have to switch all of your current setup to this. Each part can be used separately and you can substitute each part with your own solution.

This example is using Jetbrains PHPStorm as IDE and Github as storage and CI/CD solution, however you can of course use any other similar solution you want. The following setup description is here to not force you to reinvent the wheel for all of this, but to benefit from the works of others in this area. However there might be several reasons why you can't use one or the other tool in here and then you are encouraged to adapt this to your situation.

## Storing your source code

The first question is how to store your source code. While version control is a standard nowadays, how to structure the repository is still something which is left to the individual developer.
In this first chapter we are going through a possible structure of a git repository for your extension.

To read more go to the [Repository Setup](repo.md).

## IDE setup

The next section handles the configuration of PHPStorm.

To read more go to the [IDE Setup](ide.md).

## Release handling

With the setup of our repo and IDE we do have an extension to release. This section handles building a release with JoRobo.

To read more go to the [Release handling](release.md).

## Quality Assurance

Learn how to use phpstan to find bugs and how a consistent codestyle can help you.

To read more go to the [Quality Assurance setup](checks.md).

## Automated testing


## Step-by-step list to create setup for an existing extension

See the [Checklist](checklist.md).
Empty file.
12 changes: 12 additions & 0 deletions docs/building-extensions/development/repo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# How to store your code



## Extension and Repository Structure

Creating an extension (or writing any code) isn't just tinkering with the code until it somehow works, but also keeping an overview of both your current changes and the changes over time.
Even in tiny, one-off projects, you want to see what changes you made in the last hour and for longer running projects, you want to have a log of what you have done last week or 2 months ago.
That is why you should **always** use a version control system.
It doesn't matter if it is git, mercury or even subversion, but you want to see all the changes you did since your last commit and of course you want to be able to understand what you thought last time you worked on this code by reading the commit messages.

This tutorial concentrates on git and [Github.com](https://github.com). As of writing this tutorial, Github provides free unlimited public and private repositories
Empty file.