Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 2 additions & 3 deletions Annotations/GlobalApiComponents.php
Comment thread
snake14 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

/**
* @OA\OpenApi(
* openapi="3.1.0",
* security={{"MatomoToken": {}}},
* @OA\ExternalDocumentation(
* description="Matomo Reporting API developer page",
Expand Down Expand Up @@ -58,7 +57,7 @@
* description="Generic Matomo success payload.",
* required={"result","message"},
* additionalProperties=true,
* @OA\Property(property="result", type="string", enum={"success"}, example="success"),
* @OA\Property(property="result", type="string", example="success"),
* @OA\Property(property="message", type="string", example="ok"),
* @OA\Property(property="code", type="integer", example="200")
* )
Expand All @@ -70,7 +69,7 @@
* description="Generic Matomo error payload.",
* required={"result","message"},
* additionalProperties=true,
* @OA\Property(property="result", type="string", enum={"error"}, example="error"),
* @OA\Property(property="result", type="string", example="error"),
* @OA\Property(property="message", type="string", example="There was an error"),
* @OA\Property(property="code", type="integer")
* )
Expand Down
28 changes: 28 additions & 0 deletions README.md
Comment thread
snake14 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,31 @@
## Description

Allow generating OpenAPI documentation for the Matomo public APIs.

## Dependencies
This plugin had its vendored dependencies scoped using [matomo scoper](https://github.com/matomo-org/matomo-scoper). This means that composer packages are prefixed so that they won't conflict with the same libraries used by other plugins.
If you need to update a dependency, you should be able to run `composer install` to populate the vendor directory and then follow the [instructions for scoping a plugin](https://github.com/matomo-org/matomo-scoper#how-to-scope-a-matomo-plugin). Since the scoper.inc.php file already exists, it will hopefully be as simple as running the scoper for this plugin. Once that's done, you'll also need to make some of the dependencies compatible with Matomo's minimum supported version of PHP.
This is done using the [Rector library](https://github.com/rectorphp/rector-downgrade-php). It's preferable that you install the composer package in a separate project and point to this project so that it doesn't get committed in this project. You should also have a config file saved containing the following:
```php
<?php

use Rector\Config\RectorConfig;

return static function (RectorConfig $rectorConfig): void {
// Matomo requires PHP >= 7.2.5, but PHP 7.3 is close enough. We don't want to downgrade further than necessary.
$rectorConfig->sets([
\Rector\Set\ValueObject\DowngradeLevelSetList::DOWN_TO_PHP_73
]);

$rectorConfig->skip([
\Rector\DowngradePhp80\Rector\Class_\DowngradeAttributeToAnnotationRector::class,
// Skip downgrading Token for php-parser since it already provides a polyfill
\Rector\DowngradePhp80\Rector\StaticCall\DowngradePhpTokenRector::class => [
'*/vendor/prefixed/nikic/php-parser/*',
],
]);
};
```
With all that in place, you should be able to run Rector like so: `vendor/bin/rector process {path_to_this_plugin/vendor/prefixed} --config={path_to_config_file}`

> **_NOTE:_** For Matomo developers, there's an internal DevPluginCommands plugin with a command that handles scoping and running Rector. See the SearchEngineKeywordsPerformance plugin's README.md for more details.
17 changes: 11 additions & 6 deletions Specs/SpecGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@

namespace Piwik\Plugins\OpenApiDocs\Specs;

use OpenApi\Annotations\OpenApi;
use OpenApi\Generator;
use Matomo\Dependencies\OpenApiDocs\OpenApi\Annotations\OpenApi;
use Matomo\Dependencies\OpenApiDocs\OpenApi\Generator;
use Piwik\Container\StaticContainer;
use Piwik\Log\LoggerInterface;
use Piwik\Log\NullLogger;
Expand Down Expand Up @@ -60,6 +60,7 @@ public function generatePluginDoc(string $pluginName, string $format = 'json', s
* @throws \Piwik\Exception\DI\DependencyException
* @throws \Piwik\Exception\DI\NotFoundException
* @throws \Piwik\Exception\PluginDeactivatedException
* @throws \Exception
*/
public function generateSpec(array $pluginNames, string $format = 'json', string $version = OpenApiDocs::DEFAULT_SPEC_VERSION, bool $writeToFile = false): string
{
Expand All @@ -73,17 +74,21 @@ public function generateSpec(array $pluginNames, string $format = 'json', string

$pluginDir = Manager::getInstance()::getPluginDirectory($pluginName);
$pluginAnnotationsSource = $pluginDir . '/API.php';
$openapi = (new Generator(StaticContainer::get(NullLogger::class)))->generate([
$pluginAnnotationsSource,
]);
try {
$openapi = (new Generator(StaticContainer::get(NullLogger::class)))->generate([
$pluginAnnotationsSource,
]);
} catch (\Throwable $e) {
throw new \Exception('There was an error testing the API annotations for plugin ' . $pluginName, 0, $e);
}
if (trim($openapi->toYaml()) === 'openapi: ' . OpenApi::DEFAULT_VERSION) {
throw new \Exception("The $pluginName plugin's API class does not appear to be annotated yet.");
}
$pluginDirs[$pluginName] = $pluginAnnotationsSource;
}

$generator = new Generator(StaticContainer::get(LoggerInterface::class));
$openapi = $generator->generate(array_merge([
$openapi = $generator->setVersion(OpenApi::VERSION_3_1_0)->generate(array_merge([
$currentPluginDir . '/Annotations/GlobalApiComponents.php',
], $pluginDirs));

Expand Down
6 changes: 2 additions & 4 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
{
"require": {
"zircote/swagger-php": "^5.1.4",
"doctrine/annotations": "^2.0",
"symfony/yaml": "^6.4",
"symfony/finder": "^6.4"
"zircote/swagger-php": "^5.4",
"doctrine/annotations": "^2.0"
Comment thread
snake14 marked this conversation as resolved.
},
"replace": {
"monolog/monolog": "*",
Expand Down
80 changes: 46 additions & 34 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"license": "GPL v3+",
"homepage": "https:\/\/matomo.org",
"require": {
"php": ">=8.1.0",
"matomo": ">=5.0.0-stable,<6.0.0-b1"
},
"authors": [
Expand Down
23 changes: 21 additions & 2 deletions scoper.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
->exclude('lang')
->exclude('javascripts')
->exclude('vue')
->notName(['scoper.inc.php', 'Controller.php'])
->notName(['scoper.inc.php'])
->filter(function (\SplFileInfo $file) {
return !($file->isLink() && $file->isDir());
})
Expand Down Expand Up @@ -56,7 +56,26 @@
'force-no-global-alias' => $forceNoGlobalAlias,
'prefix' => 'Matomo\\Dependencies\\' . $pluginName,
'finders' => $finders,
'patchers' => [],
'patchers' => [
// Patcher for making sure that AbstractAnnotation is looking for the correct root
static function (string $filePath, string $prefix, string $content) use ($isRenamingReferences): string {
if ($isRenamingReferences) {
return $content;
}

// Fix the string reference of a scoped dependency in the AbstractAnnotation class
$escapedPrefix = str_replace('\\', '\\\\', $prefix);
if ($filePath === __DIR__ . '/vendor/zircote/swagger-php/src/Annotations/AbstractAnnotation.php') {
$content = str_replace(
'OpenApi\\\\Annotations\\\\',
"{$escapedPrefix}\\\\OpenApi\\\\Annotations\\\\",
$content
);
}

return $content;
},
],
'include-namespaces' => $namespacesToIncludeRegexes,
'exclude-namespaces' => $namespacesToExclude,
'exclude-constants' => [
Expand Down
Loading