added example for developpers module
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
name: Page Example
|
||||
type: module
|
||||
description: 'Demonstrates how to display a page at a given URL.'
|
||||
package: Example modules
|
||||
# core: 8.x
|
||||
dependencies:
|
||||
- drupal:node
|
||||
- examples:examples
|
||||
|
||||
# Information added by Drupal.org packaging script on 2017-12-17
|
||||
version: '8.x-1.x-dev'
|
||||
core: '8.x'
|
||||
project: 'examples'
|
||||
datestamp: 1513537386
|
||||
@@ -0,0 +1,12 @@
|
||||
page_example.description:
|
||||
title: Page Example
|
||||
route_name: page_example_description
|
||||
expanded: TRUE
|
||||
|
||||
page_example.simple:
|
||||
title: Simple - no arguments
|
||||
route_name: page_example_simple
|
||||
parent: page_example.description
|
||||
|
||||
# We can't define a menu link for the page_example_arguments route, because it
|
||||
# requires path arguments.
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Module file for page_example_module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
|
||||
/**
|
||||
* @defgroup page_example Example: Page
|
||||
* @ingroup examples
|
||||
* @{
|
||||
* This example demonstrates how a module can display a page at a given URL.
|
||||
*
|
||||
* It's important to understand how the menu system works in order to
|
||||
* implement your own pages. See the Menu Example module for some insight.
|
||||
*
|
||||
* @see menu_example
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implements hook_help().
|
||||
*
|
||||
* Through hook_help(), a module can make documentation available to the user
|
||||
* for the module as a whole or for specific routes. Where the help appears
|
||||
* depends on the $route_name specified.
|
||||
*
|
||||
* Help text will be displayed in the region designated for help text. Typically
|
||||
* this is the 'Help' region which can be found at admin/structure/block.
|
||||
*
|
||||
* The help text in the first example below, will appear on the simple page at
|
||||
* examples/page-example/simple.
|
||||
*
|
||||
* The second example text will be available on the admin help page (admin/help)
|
||||
* in the list of help topics using the name of the module. To specify help in
|
||||
* the admin section combine the special route name of 'help.page' with the
|
||||
* module's machine name, as in 'help.page.page_example' below.
|
||||
*
|
||||
* See the Help text standard page for the proposed format of help texts.
|
||||
*
|
||||
* @see https://www.drupal.org/documentation/help-text-standards
|
||||
*
|
||||
* @see hook_help()
|
||||
*/
|
||||
function page_example_help($route_name, RouteMatchInterface $route_match) {
|
||||
switch ($route_name) {
|
||||
case 'page_example_simple':
|
||||
// Help text for the simple page registered for this path.
|
||||
return t('This is help text for the simple page.');
|
||||
|
||||
case 'help.page.page_example':
|
||||
// Help text for the admin section, using the module name in the path.
|
||||
return t("This is help text created in page example's implementation of hook_help().");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} End of "defgroup page_example".
|
||||
*/
|
||||
@@ -0,0 +1,11 @@
|
||||
# Since the access to our new custom pages will be granted based on special
|
||||
# permissions, we need to define what those permissions are here. This ensures
|
||||
# that they are available to enable on the permissions administration pages.
|
||||
|
||||
'access simple page':
|
||||
title: Access simple page
|
||||
description: Allow users to access simple page
|
||||
|
||||
'access arguments page':
|
||||
title: Access page with arguments
|
||||
description: Allow users to access page with arguments
|
||||
@@ -0,0 +1,55 @@
|
||||
# In order to to create pages it is necessary to define routes for them. A route
|
||||
# maps a URL path to a controller. It defines with what function or method will
|
||||
# be called when a URL is accessed. The following lines defines three of them
|
||||
# for this module.
|
||||
|
||||
# Menu items corresponding to these URLs are defined separately in the
|
||||
# page_example.menu_links.yml file.
|
||||
|
||||
# If the user accesses http://example.com/?q=examples/page-example, the routing
|
||||
# system will look for a route with that path. In this case it will find a
|
||||
# match, and execute the _controller callback. In this case the callback is
|
||||
# defined as a classname
|
||||
# ("\Drupal\page_example\Controller\PageExampleController") and a method
|
||||
# ("description").
|
||||
|
||||
# Access to this path is not restricted. This is notated as _access: 'TRUE'.
|
||||
page_example_description:
|
||||
path: 'examples/page-example'
|
||||
defaults:
|
||||
_controller: '\Drupal\page_example\Controller\PageExampleController::description'
|
||||
_title: 'Page Example'
|
||||
requirements:
|
||||
_permission: 'access content'
|
||||
|
||||
# If the user accesses http://example.com/?q=examples/page-example/simple,
|
||||
# the routing system will look for a route with that path. In this case it will
|
||||
# find a match, and execute the _controller callback. Access to this path
|
||||
# requires "access simple page" permission.
|
||||
page_example_simple:
|
||||
path: 'examples/page-example/simple'
|
||||
defaults:
|
||||
_controller: '\Drupal\page_example\Controller\PageExampleController::simple'
|
||||
_title: 'Simple - no arguments'
|
||||
requirements:
|
||||
_permission: 'access simple page'
|
||||
|
||||
# If the user accesses
|
||||
# http://example.com/?q=examples/page-example/arguments/1/2, the routing system
|
||||
# will first look for examples/page-example/arguments/1/2. Not finding a match,
|
||||
# it will look for examples/page-example/arguments/1/{*}. Again not finding a
|
||||
# match, it will look for examples/page-example/arguments/{*}/2. Yet again not
|
||||
# finding a match, it will look for examples/page-example/arguments/{*}/{*}.
|
||||
# This time it finds a match, and so it will execute the _controller callback.
|
||||
# In this case, it's PageExampleController::arguments().
|
||||
|
||||
# Since the parameters are passed to the function after the match, the function
|
||||
# can do additional checking or make use of them before executing the callback
|
||||
# function. The placeholder names "first" and "second" are arbitrary but must
|
||||
# match the variable names in the callback method, e.g. "$first" and "$second".
|
||||
page_example_arguments:
|
||||
path: 'examples/page-example/arguments/{first}/{second}'
|
||||
defaults:
|
||||
_controller: '\Drupal\page_example\Controller\PageExampleController::arguments'
|
||||
requirements:
|
||||
_permission: 'access arguments page'
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\page_example\Controller;
|
||||
|
||||
use Drupal\Core\Controller\ControllerBase;
|
||||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||
use Drupal\examples\Utility\DescriptionTemplateTrait;
|
||||
|
||||
/**
|
||||
* Controller routines for page example routes.
|
||||
*/
|
||||
class PageExampleController extends ControllerBase {
|
||||
|
||||
use DescriptionTemplateTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function getModuleName() {
|
||||
return 'page_example';
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a simple page.
|
||||
*
|
||||
* The router _controller callback, maps the path
|
||||
* 'examples/page-example/simple' to this method.
|
||||
*
|
||||
* _controller callbacks return a renderable array for the content area of the
|
||||
* page. The theme system will later render and surround the content with the
|
||||
* appropriate blocks, navigation, and styling.
|
||||
*/
|
||||
public function simple() {
|
||||
return [
|
||||
'#markup' => '<p>' . $this->t('Simple page: The quick brown fox jumps over the lazy dog.') . '</p>',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* A more complex _controller callback that takes arguments.
|
||||
*
|
||||
* This callback is mapped to the path
|
||||
* 'examples/page-example/arguments/{first}/{second}'.
|
||||
*
|
||||
* The arguments in brackets are passed to this callback from the page URL.
|
||||
* The placeholder names "first" and "second" can have any value but should
|
||||
* match the callback method variable names; i.e. $first and $second.
|
||||
*
|
||||
* This function also demonstrates a more complex render array in the returned
|
||||
* values. Instead of rendering the HTML with theme('item_list'), content is
|
||||
* left un-rendered, and the theme function name is set using #theme. This
|
||||
* content will now be rendered as late as possible, giving more parts of the
|
||||
* system a chance to change it if necessary.
|
||||
*
|
||||
* Consult @link http://drupal.org/node/930760 Render Arrays documentation
|
||||
* @endlink for details.
|
||||
*
|
||||
* @param string $first
|
||||
* A string to use, should be a number.
|
||||
* @param string $second
|
||||
* Another string to use, should be a number.
|
||||
*
|
||||
* @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
|
||||
* If the parameters are invalid.
|
||||
*/
|
||||
public function arguments($first, $second) {
|
||||
// Make sure you don't trust the URL to be safe! Always check for exploits.
|
||||
if (!is_numeric($first) || !is_numeric($second)) {
|
||||
// We will just show a standard "access denied" page in this case.
|
||||
throw new AccessDeniedHttpException();
|
||||
}
|
||||
|
||||
$list[] = $this->t("First number was @number.", ['@number' => $first]);
|
||||
$list[] = $this->t("Second number was @number.", ['@number' => $second]);
|
||||
$list[] = $this->t('The total was @number.', ['@number' => $first + $second]);
|
||||
|
||||
$render_array['page_example_arguments'] = [
|
||||
// The theme function to apply to the #items.
|
||||
'#theme' => 'item_list',
|
||||
// The list itself.
|
||||
'#items' => $list,
|
||||
'#title' => $this->t('Argument Information'),
|
||||
];
|
||||
return $render_array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
{#
|
||||
/**
|
||||
* @file
|
||||
* Contains the text of the page_example explanation page
|
||||
*/
|
||||
#}
|
||||
|
||||
{% set page_example_simple = path('page_example_simple') %}
|
||||
{% set page_example_arguments = path('page_example_arguments', {'first': 23, 'second': 56}) %}
|
||||
|
||||
{% trans %}
|
||||
<p>The Page example module provides two pages, "simple" and "arguments".</p>
|
||||
<p>The <a href={{ page_example_simple }}>simple page</a> just returns a renderable array for display.</p>
|
||||
<p>The <a href={{ page_example_arguments }}>arguments page</a> takes two arguments and displays them, as in {{ page_example_arguments }}</p>
|
||||
{% endtrans %}
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
<?php
|
||||
|
||||
namespace Drupal\Tests\page_example\Functional;
|
||||
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
|
||||
/**
|
||||
* Creates page and render the content based on the arguments passed in the URL.
|
||||
*
|
||||
* @group page_example
|
||||
* @group examples
|
||||
*/
|
||||
class PageExampleTest extends BrowserTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = ['page_example'];
|
||||
|
||||
/**
|
||||
* The installation profile to use with this test.
|
||||
*
|
||||
* We need the 'minimal' profile in order to make sure the Tool block is
|
||||
* available.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $profile = 'minimal';
|
||||
|
||||
/**
|
||||
* User object for our test.
|
||||
*
|
||||
* @var \Drupal\user\Entity\User
|
||||
*/
|
||||
protected $webUser;
|
||||
|
||||
/**
|
||||
* Generates a random string of ASCII numeric characters (values 48 to 57).
|
||||
*
|
||||
* @param int $length
|
||||
* Length of random string to generate.
|
||||
*
|
||||
* @return string
|
||||
* Randomly generated string.
|
||||
*/
|
||||
protected static function randomNumber($length = 8) {
|
||||
$str = '';
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
$str .= chr(mt_rand(48, 57));
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that current user has no access to page.
|
||||
*
|
||||
* @param string $url
|
||||
* URL to verify.
|
||||
*/
|
||||
public function pageExampleVerifyNoAccess($url) {
|
||||
// Test that page returns 403 Access Denied.
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->statusCodeEquals(403);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing menu links.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* Array of page -> link relationships to check for, with the permissions
|
||||
* required to access them:
|
||||
* - Permission machine name. Empty string means no login.
|
||||
* - Array of link information:
|
||||
* - Key is path to the page where the link should appear.
|
||||
* - Value is the link that should appear on the page.
|
||||
*/
|
||||
public function providerMenuLinks() {
|
||||
return [
|
||||
[
|
||||
'',
|
||||
['' => '/examples/page-example'],
|
||||
],
|
||||
[
|
||||
'access simple page',
|
||||
['/examples/page-example' => '/examples/page-example/simple'],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify and validate that default menu links were loaded for this module.
|
||||
*
|
||||
* @dataProvider providerMenuLinks
|
||||
*/
|
||||
public function testPageExampleLinks($permission, $links) {
|
||||
if ($permission) {
|
||||
$user = $this->drupalCreateUser([$permission]);
|
||||
$this->drupalLogin($user);
|
||||
}
|
||||
foreach ($links as $page => $path) {
|
||||
$this->drupalGet($page);
|
||||
$this->assertSession()->linkByHrefExists($path);
|
||||
}
|
||||
if ($permission) {
|
||||
$this->drupalLogout();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main test.
|
||||
*
|
||||
* Login user, create an example node, and test page functionality through
|
||||
* the admin and user interfaces.
|
||||
*/
|
||||
public function testPageExample() {
|
||||
$assert_session = $this->assertSession();
|
||||
// Verify that anonymous user can't access the pages created by
|
||||
// page_example module.
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/simple');
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/arguments/1/2');
|
||||
|
||||
// Create a regular user and login.
|
||||
$this->webUser = $this->drupalCreateUser();
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Verify that regular user can't access the pages created by
|
||||
// page_example module.
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/simple');
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/arguments/1/2');
|
||||
|
||||
// Create a user with permissions to access 'simple' page and login.
|
||||
$this->webUser = $this->drupalCreateUser(['access simple page']);
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Verify that user can access simple content.
|
||||
$this->drupalGet('/examples/page-example/simple');
|
||||
$assert_session->statusCodeEquals(200);
|
||||
$assert_session->pageTextContains('The quick brown fox jumps over the lazy dog.');
|
||||
|
||||
// Check if user can't access arguments page.
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/arguments/1/2');
|
||||
|
||||
// Create a user with permissions to access 'simple' page and login.
|
||||
$this->webUser = $this->drupalCreateUser(['access arguments page']);
|
||||
$this->drupalLogin($this->webUser);
|
||||
|
||||
// Verify that user can access arguments content.
|
||||
$first = self::randomNumber(3);
|
||||
$second = self::randomNumber(3);
|
||||
$this->drupalGet('/examples/page-example/arguments/' . $first . '/' . $second);
|
||||
$assert_session->statusCodeEquals(200);
|
||||
// Verify argument usage.
|
||||
$assert_session->pageTextContains(t('First number was @number.', ['@number' => $first]));
|
||||
$assert_session->pageTextContains(t('Second number was @number.', ['@number' => $second]));
|
||||
$assert_session->pageTextContains(t('The total was @number.', ['@number' => $first + $second]));
|
||||
|
||||
// Verify incomplete argument call to arguments content.
|
||||
$this->drupalGet('/examples/page-example/arguments/' . $first . '/');
|
||||
$assert_session->statusCodeEquals(404);
|
||||
|
||||
// Verify 403 for invalid second argument.
|
||||
$this->drupalGet('/examples/page-example/arguments/' . $first . '/non-numeric-argument');
|
||||
$assert_session->statusCodeEquals(403);
|
||||
|
||||
// Verify 403 for invalid first argument.
|
||||
$this->drupalGet('/examples/page-example/arguments/non-numeric-argument/' . $second);
|
||||
$assert_session->statusCodeEquals(403);
|
||||
|
||||
// Check if user can't access simple page.
|
||||
$this->pageExampleVerifyNoAccess('examples/page-example/simple');
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user