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
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .laminas-ci.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"ignore_php_platform_requirements": {
"8.4": true
},
"backwardCompatibilityCheck": true
}
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# dot-navigation

![OSS Lifecycle](https://img.shields.io/osslifecycle/dotkernel/dot-navigation)
![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-navigation/3.5.1)
![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-navigation/4.0.0)

[![GitHub issues](https://img.shields.io/github/issues/dotkernel/dot-navigation)](https://github.com/dotkernel/dot-navigation/issues)
[![GitHub forks](https://img.shields.io/github/forks/dotkernel/dot-navigation)](https://github.com/dotkernel/dot-navigation/network)
[![GitHub stars](https://img.shields.io/github/stars/dotkernel/dot-navigation)](https://github.com/dotkernel/dot-navigation/stargazers)
[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-navigation)](https://github.com/dotkernel/dot-navigation/blob/3.0/LICENSE.md)
[![GitHub license](https://img.shields.io/github/license/dotkernel/dot-navigation)](https://github.com/dotkernel/dot-navigation/blob/4.0/LICENSE.md)

[![Build Static](https://github.com/dotkernel/dot-navigation/actions/workflows/static-analysis.yml/badge.svg?branch=3.0)](https://github.com/dotkernel/dot-navigation/actions/workflows/static-analysis.yml)
[![Build Static](https://github.com/dotkernel/dot-navigation/actions/workflows/static-analysis.yml/badge.svg?branch=4.0)](https://github.com/dotkernel/dot-navigation/actions/workflows/static-analysis.yml)
[![codecov](https://codecov.io/gh/dotkernel/dot-navigation/graph/badge.svg?token=AI9WFYDDX9)](https://codecov.io/gh/dotkernel/dot-navigation)

[![SymfonyInsight](https://insight.symfony.com/projects/68b7c728-4cc9-40ac-a3be-cf17f9b2eaf1/big.svg)](https://insight.symfony.com/projects/68b7c728-4cc9-40ac-a3be-cf17f9b2eaf1)

Allows you to easily define and parse menus inside templates, configuration based approach.

## Installation

Run

composer require dotkernel/dot-navigation
```shell
composer require dotkernel/dot-navigation
```

Merge `ConfigProvider` to your application's configuration.

Expand Down
30 changes: 10 additions & 20 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,28 @@

## Supported Versions


| Version | Supported | PHP Version |
|---------|--------------------|---------------------------------------------------------------------------------------------------------------|
| 3.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-navigation/3.4.2)|

| Version | Supported | PHP Version |
|---------|--------------------|----------------------------------------------------------------------------------------------------------------|
| 4.x | :white_check_mark: | ![PHP from Packagist (specify version)](https://img.shields.io/packagist/php-v/dotkernel/dot-navigation/4.0.0) |
| <= 3.x | :x: | |

## Reporting Potential Security Issues

If you have encountered a potential security vulnerability in this project,
please report it to us at <security@dotkernel.com>. We will work with you to
verify the vulnerability and patch it.
If you have encountered a potential security vulnerability in this project, please report it to us at <security@dotkernel.com>.
We will work with you to verify the vulnerability and patch it.

When reporting issues, please provide the following information:

- Component(s) affected
- A description indicating how to reproduce the issue
- A summary of the security vulnerability and impact

We request that you contact us via the email address above and give the
project contributors a chance to resolve the vulnerability and issue a new
release prior to any public exposure; this helps protect the project's
users, and provides them with a chance to upgrade and/or update in order to
protect their applications.

We request that you contact us via the email address above and give the project contributors a chance to resolve the vulnerability and issue a new release prior to any public exposure;
this helps protect the project's users, and provides them with a chance to upgrade and/or update in order to protect their applications.

## Policy

If we verify a reported security vulnerability, our policy is:

- We will patch the current release branch, as well as the immediate prior minor
release branch.

- After patching the release branches, we will immediately issue new security
fix releases for each patched release branch.

- We will patch the current release branch, as well as the immediate prior minor release branch.
- After patching the release branches, we will immediately issue new security fix releases for each patched release branch.
15 changes: 8 additions & 7 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dotkernel/dot-navigation",
"type": "library",
"description": "DotKernel navigation component",
"description": "Dotkernel navigation component",
"license": "MIT",
"homepage": "https://github.com/dotkernel/dot-navigation",
"keywords": [
Expand All @@ -13,7 +13,7 @@
],
"authors": [
{
"name": "DotKernel Team",
"name": "Dotkernel Team",
"email": "team@dotkernel.com"
}
],
Expand All @@ -24,17 +24,17 @@
}
},
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0",
"dotkernel/dot-authorization": "^3.4.1",
"dotkernel/dot-helpers": "^3.5.1",
"dotkernel/dot-helpers": "^3.7.0",
"laminas/laminas-escaper": "^2.13.0",
"laminas/laminas-servicemanager": "^3.22.1",
"laminas/laminas-servicemanager": "^4.0",
"mezzio/mezzio-template": "^2.9.0",
"psr/http-message": "^1.0 || ^2.0",
"psr/http-server-middleware": "^1.0.2"
},
"require-dev": {
"laminas/laminas-coding-standard": "^2.5.0",
"laminas/laminas-coding-standard": "^3.0.0",
"phpunit/phpunit": "^10.4.2",
"vimeo/psalm": "^5.16.0"
},
Expand All @@ -51,7 +51,8 @@
"scripts": {
"check": [
"@cs-check",
"@test"
"@test",
"@static-analysis"
],
"cs-check": "phpcs",
"cs-fix": "phpcbf",
Expand Down
1 change: 0 additions & 1 deletion docs/book/index.md

This file was deleted.

1 change: 1 addition & 0 deletions docs/book/index.md
2 changes: 1 addition & 1 deletion docs/book/v3/overview.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Overview

`dot-navigation` is DotKernel's component that allows you to easily define and parse menus inside templates, using a configuration based approach.
`dot-navigation` is Dotkernel's component that allows you to easily define and parse menus inside templates, using a configuration based approach.
13 changes: 13 additions & 0 deletions docs/book/v4/components.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Components

A menu, or navigation container, is a class implementing the \RecursiveIterator interface. It has a hierarchical structure, with nodes called pages(see the `Page` class) that may have children. It is basically a tree

A Page extends the NavigationContainer class. The NavigationContainer is the top most node which represents the entire menu. The children of this node are Page instances that defines each navigation item.

A page has a reference to its parent, and can have options and attributes. There are no limitation on what is accepted as options or attributes.

Options can be any piece of information that describes a page. Some predefined options exists, in order for the navigation module to work seamlessly with other dot modules.

Attributes are key value pairs that defines the menu item. They are usually inserted as html attributes when parsing the menu, but of course, this is implementation specific.

A `NavigationService` class, is the service that handles all defined menu container. It can fetch the container from its provider, check if a page is active or not and get the page's generated URI.
7 changes: 7 additions & 0 deletions docs/book/v4/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Configuration

After installation, register `dot-navigation` in your project by adding the below line to your configuration aggregator (usually: `config/config.php`):

Dot\Navigation\ConfigProvider::class,

Locate dot-navigation's distributable config file `vendor/dotkernel/dot-navigation/config/autoload/navigation.global.php.dist` and duplicate it in your project as `config/autoload/navigation.global.php`
7 changes: 7 additions & 0 deletions docs/book/v4/container-providers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Container providers

Each menu can be created from different sources. The responsibility of creating a menu container from the source falls on a container provider.

Each provider must implement the interface `ProviderInterface` and be registered in the ProviderPluginManager.

We offer just one provider for now, `ArrayProvider`, that is able to fetch and create a menu container from a php array that is defined in the configuration file.
5 changes: 5 additions & 0 deletions docs/book/v4/installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Installation

Install `dotkernel/dot-navigation` by executing the following Composer command:

composer require dotkernel/dot-navigation
11 changes: 11 additions & 0 deletions docs/book/v4/navigation-renderer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# NavigationRenderer

Used to render the navigation container in a displayable format. It can render a simple HTML ul list or use a partial template, to render the menu in a template engine.

The partial method is usually the more flexible one, custom rules can be defined and checked in the template.

If you are using twig, there is already a twig extension provided in package dot-twigrenderer, that you can use to easily parse the menus inside your templates

When using the partial method, the template will receive as parameters the container, the navigation service and any extra parameters set by the developer.

Navigation containers are referred, when parsed, by their name, as defined in the configuration file.
3 changes: 3 additions & 0 deletions docs/book/v4/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Overview

`dot-navigation` is Dotkernel's component that allows you to easily define and parse menus inside templates, using a configuration based approach.
7 changes: 7 additions & 0 deletions docs/book/v4/required-page-options.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Required page options and attributes

The following are options that each page should define in the configuration

* `label` - the text of the menu item
* `route` or `uri` - defines the route or link the menu item will have
* `permission` - can be used optionally, if authorization service is present, in order to omit menu items that are not authorized to visit.
58 changes: 58 additions & 0 deletions docs/book/v4/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Usage

Below is an example with content of `config/autoload/navigation.global.php`.

Here we can change or modify the menu structure that will be rendered in the application we are building.

```php
<?php

return [
'dot_navigation' => [
//enable menu item active if any child is active
'active_recursion' => true,

//map a provider name to its config
'containers' => [
'default' => [
'type' => 'ArrayProvider',
'options' => [
'items' => [
[
'options' => [
'label' => 'Menu #1',
'route' => [
'route_name' => 'home',
'route_params' => [],
'query_params' => [],
'fragment_id' => null,
'options' => [],

//the below parameters are not used in route generation
//they are used in finding if a page is active by omitting some parameters from the check
'ignore_params' => []
],
],
'attributes' => [
'name' => 'Menu #1',
]
],
[
'options' => [
'label' => 'Menu #2',
'route' => ['route_name' => 'home'],
],
'attributes' => [
'name' => 'Menu #1',
]
]
],
],
],
],

//register custom providers here
'provider_manager' => [],
],
];
```
14 changes: 12 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@ docs_dir: docs/book
site_dir: docs/html
extra:
project: Packages
current_version: v3
current_version: v4
versions:
- v4
- v3
nav:
- Home: index.md
- v4:
- Overview: v4/overview.md
- Configuration: v4/configuration.md
- Installation: v4/installation.md
- Components: v4/components.md
- "Container Providers": v4/container-providers.md
- "Navigation Renderer": v4/navigation-renderer.md
- "Required Page Options": v4/required-page-options.md
- Usage: v4/usage.md
- v3:
- Overview: v3/overview.md
- Configuration: v3/configuration.md
Expand All @@ -17,7 +27,7 @@ nav:
- "Required Page Options": v3/required-page-options.md
- Usage: v3/usage.md
site_name: dot-navigation
site_description: "DotKernel's component that allows you to easily define and parse menus inside templates, using a configuration based approach."
site_description: "Dotkernel's component that allows you to easily define and parse menus inside templates, using a configuration based approach."
repo_url: "https://github.com/dotkernel/dot-navigation"
plugins:
- search
5 changes: 0 additions & 5 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,4 @@
<code>RecursiveIterator</code>
</MissingTemplateParam>
</file>
<file src="src/Provider/ProviderPluginManager.php">
<MissingTemplateParam>
<code>ProviderPluginManager</code>
</MissingTemplateParam>
</file>
</files>
6 changes: 5 additions & 1 deletion src/Provider/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Dot\Navigation\Provider;

use Dot\Navigation\Exception\RuntimeException;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;

class Factory implements FactoryInterface
Expand All @@ -18,14 +19,17 @@ public function __construct(ContainerInterface $container, ?ProviderPluginManage
$this->providerPluginManager = $providerPluginManager;
}

/**
* @throws ContainerExceptionInterface
*/
public function create(array $specs): ProviderInterface
{
$type = $specs['type'] ?? '';
if (empty($type)) {
throw new RuntimeException('Undefined navigation provider type');
}

return $this->getProviderPluginManager()->get($type, $specs['options'] ?? null);
return $this->getProviderPluginManager()->build($type, $specs['options'] ?? null);
}

public function getProviderPluginManager(): ProviderPluginManager
Expand Down
30 changes: 24 additions & 6 deletions src/Provider/ProviderPluginManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,42 @@
namespace Dot\Navigation\Provider;

use Laminas\ServiceManager\AbstractPluginManager;
use Laminas\ServiceManager\Exception\InvalidServiceException;
use Laminas\ServiceManager\Factory\InvokableFactory;

use function gettype;
use function is_object;
use function sprintf;

/**
* @template InstanceType
* @extends AbstractPluginManager<InstanceType>
*/
class ProviderPluginManager extends AbstractPluginManager
{
/** @var string $instanceOf */
protected $instanceOf = ProviderInterface::class;
protected string $instanceOf = ProviderInterface::class;

/** @var array */
protected $factories = [
protected array $factories = [
ArrayProvider::class => InvokableFactory::class,
];

/** @var string[] $aliases */
protected $aliases = [
protected array $aliases = [
'arrayprovider' => ArrayProvider::class,
'arrayProvider' => ArrayProvider::class,
'ArrayProvider' => ArrayProvider::class,
'array' => ArrayProvider::class,
'Array' => ArrayProvider::class,
];

public function validate(mixed $instance): void
{
if (! $instance instanceof $this->instanceOf) {
throw new InvalidServiceException(sprintf(
'%s can only create instances of %s; %s is invalid',
static::class,
$this->instanceOf,
is_object($instance) ? $instance::class : gettype($instance)
));
}
}
}
Loading
Loading