template rapport_dactivitees avec pdf à télécharger

This commit is contained in:
2021-03-23 13:58:22 +01:00
parent 66f835e1ff
commit f8ecbbe597
39 changed files with 526 additions and 205 deletions
+14 -9
View File
@@ -27,7 +27,6 @@ use function is_bool;
use function is_float;
use function is_int;
use function is_string;
use function strlen;
/**
* Class Validation
@@ -239,16 +238,20 @@ class Validation
$value = trim($value);
}
if (isset($params['min']) && strlen($value) < $params['min']) {
$len = mb_strlen($value);
$min = (int)($params['min'] ?? 0);
if ($min && $len < $min) {
return false;
}
if (isset($params['max']) && strlen($value) > $params['max']) {
$max = (int)($params['max'] ?? 0);
if ($max && $len > $max) {
return false;
}
$min = $params['min'] ?? 0;
if (isset($params['step']) && (strlen($value) - $min) % $params['step'] === 0) {
$step = (int)($params['step'] ?? 0);
if ($step && ($len - $min) % $step === 0) {
return false;
}
@@ -271,11 +274,13 @@ class Validation
return '';
}
$value = (string)$value;
if (!empty($params['trim'])) {
$value = trim($value);
}
return (string) $value;
return $value;
}
/**
@@ -332,7 +337,7 @@ class Validation
*/
protected static function filterLower($value, array $params)
{
return strtolower($value);
return mb_strtolower($value);
}
/**
@@ -342,7 +347,7 @@ class Validation
*/
protected static function filterUpper($value, array $params)
{
return strtoupper($value);
return mb_strtoupper($value);
}
@@ -534,7 +539,7 @@ class Validation
*/
protected static function filterNumber($value, array $params, array $field)
{
return (string)(int)$value !== (string)(float)$value ? (float) $value : (int) $value;
return (string)(int)$value !== (string)(float)$value ? (float)$value : (int)$value;
}
/**
@@ -522,12 +522,13 @@ class PageIndex extends FlexPageIndex implements PageCollectionInterface
$tmp = $child->children()->getIndex();
$child_count = $tmp->count();
$count = $filters ? $tmp->filterBy($filters, true)->count() : null;
$route = $child->getRoute();
$payload = [
'item-key' => basename($child->rawRoute() ?? $child->getKey()),
'icon' => $icon,
'title' => htmlspecialchars($child->menu()),
'route' => [
'display' => $child->getRoute()->toString(false) ?: '/',
'display' => ($route ? ($route->toString(false) ?: '/') : null) ?? '',
'raw' => $child->rawRoute(),
],
'modified' => $this->jsDate($child->modified()),
@@ -22,6 +22,7 @@ use Grav\Common\Flex\Types\Pages\Traits\PageTranslateTrait;
use Grav\Common\Language\Language;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Page\Pages;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils;
use Grav\Framework\Filesystem\Filesystem;
use Grav\Framework\Flex\FlexObject;
@@ -321,6 +322,28 @@ class PageObject extends FlexPageObject
return $this;
}
/**
* @param UserInterface $user
* @param string $action
* @param string $scope
* @param bool $isMe
* @return bool|null
*/
protected function isAuthorizedOverride(UserInterface $user, string $action, string $scope, bool $isMe): ?bool
{
// Special case: creating a new page means checking parent for its permissions.
if ($action === 'create' && !$this->exists()) {
$parent = $this->parent();
if ($parent && method_exists($parent, 'isAuthorized')) {
return $parent->isAuthorized($action, $scope, $user);
}
return false;
}
return parent::isAuthorizedOverride($user, $action, $scope, $isMe);
}
/**
* @param array $ordering
* @return PageCollection|null
@@ -15,6 +15,7 @@ use Grav\Common\Grav;
use Grav\Common\Page\Interfaces\PageCollectionInterface;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Page\Pages;
use Grav\Common\Uri;
use Grav\Common\Utils;
use Grav\Framework\Filesystem\Filesystem;
use RuntimeException;
@@ -97,6 +98,7 @@ trait PageRoutableTrait
public function activeChild(): bool
{
$grav = Grav::instance();
/** @var Uri $uri */
$uri = $grav['uri'];
/** @var Pages $pages */
$pages = $grav['pages'];
+1 -1
View File
@@ -426,7 +426,7 @@ class Grav extends Container
// Clean route for redirect
$route = preg_replace("#^\/[\\\/]+\/#", '/', $route);
if (null !== $code || $code < 300 || $code > 399) {
if ($code < 300 || $code > 399) {
$code = null;
}
@@ -198,6 +198,17 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
}
}
/**
* @param string $name
* @return void
*/
public function hide($name)
{
$this->offsetUnset($name);
unset($this->images[$name], $this->videos[$name], $this->audios[$name], $this->files[$name]);
}
/**
* Create Medium from a file.
*
+12 -10
View File
@@ -2496,21 +2496,23 @@ class Page implements PageInterface
*/
public function activeChild()
{
$uri = Grav::instance()['uri'];
$pages = Grav::instance()['pages'];
$grav = Grav::instance();
/** @var Uri $uri */
$uri = $grav['uri'];
/** @var Pages $pages */
$pages = $grav['pages'];
$uri_path = rtrim(urldecode($uri->path()), '/');
$routes = Grav::instance()['pages']->routes();
$routes = $pages->routes();
if (isset($routes[$uri_path])) {
$page = $pages->find($uri->route());
/** @var PageInterface|null $child_page */
$child_page = $pages->find($uri->route())->parent();
if ($child_page) {
while (!$child_page->root()) {
if ($this->path() === $child_page->path()) {
return true;
}
$child_page = $child_page->parent();
$child_page = $page ? $page->parent() : null;
while ($child_page && !$child_page->root()) {
if ($this->path() === $child_page->path()) {
return true;
}
$child_page = $child_page->parent();
}
}
+116 -73
View File
@@ -880,103 +880,146 @@ class Pages
}
/**
* alias method to return find a page.
* Find a page based on route.
*
* @param string $route The relative URL of the page
* @param bool $all
* @param string $route The route of the page
* @param bool $all If true, return also non-routable pages, otherwise return null if page isn't routable
* @return PageInterface|null
*/
public function find($route, $all = false)
{
return $this->dispatch($route, $all, false);
$route = urldecode((string)$route);
// Fetch page if there's a defined route to it.
$path = $this->routes[$route] ?? null;
$page = null !== $path ? $this->get($path) : null;
// Try without trailing slash
if (null === $page && Utils::endsWith($route, '/')) {
$path = $this->routes[rtrim($route, '/')] ?? null;
$page = null !== $path ? $this->get($path) : null;
}
if (!$all && !isset($this->grav['admin'])) {
if (null === $page || !$page->routable()) {
// If the page cannot be accessed, look for the site wide routes and wildcards.
$page = $this->findSiteBasedRoute($route) ?? $page;
}
}
return $page;
}
/**
* Check site based routes.
*
* @param string $route
* @return PageInterface|null
*/
protected function findSiteBasedRoute($route)
{
/** @var Config $config */
$config = $this->grav['config'];
$site_routes = $config->get('site.routes');
if (!is_array($site_routes)) {
return null;
}
$page = null;
// See if route matches one in the site configuration
$site_route = $site_routes[$route] ?? null;
if ($site_route) {
$page = $this->find($site_route);
} else {
// Use reverse order because of B/C (previously matched multiple and returned the last match).
foreach (array_reverse($site_routes, true) as $pattern => $replace) {
$pattern = '#^' . str_replace('/', '\/', ltrim($pattern, '^')) . '#';
try {
$found = preg_replace($pattern, $replace, $route);
if ($found && $found !== $route) {
$page = $this->find($found);
if ($page) {
return $page;
}
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage());
}
}
}
return $page;
}
/**
* Dispatch URI to a page.
*
* @param string $route The relative URL of the page
* @param bool $all
* @param bool $redirect
* @param bool $all If true, return also non-routable pages, otherwise return null if page isn't routable
* @param bool $redirect If true, allow redirects
* @return PageInterface|null
* @throws Exception
*/
public function dispatch($route, $all = false, $redirect = true)
{
$route = urldecode($route);
$page = $this->find($route, true);
// Fetch page if there's a defined route to it.
$path = $this->routes[$route] ?? null;
$page = null !== $path ? $this->get($path) : null;
// Try without trailing slash
if (!$page && Utils::endsWith($route, '/')) {
$path = $this->routes[rtrim($route, '/')] ?? null;
$page = null !== $path ? $this->get($path) : null;
// If we want all pages or are in admin, return what we already have.
if ($all || isset($this->grav['admin'])) {
return $page;
}
// Are we in the admin? this is important!
$not_admin = !isset($this->grav['admin']);
// If the page cannot be reached, look into site wide redirects, routes + wildcards
if (!$all && $not_admin) {
// If the page is a simple redirect, just do it.
if ($redirect && $page && $page->redirect()) {
$this->grav->redirectLangSafe($page->redirect());
}
// fall back and check site based redirects
if (!$page || !$page->routable()) {
// Redirect to the first child (placeholder page)
if ($redirect && $page && count($children = $page->children()->visible()->routable()->published()) > 0) {
$this->grav->redirectLangSafe($children->first()->route());
if ($page) {
$routable = $page->routable();
if ($redirect) {
if ($page->redirect()) {
// Follow a redirect page.
$this->grav->redirectLangSafe($page->redirect());
}
/** @var Config $config */
$config = $this->grav['config'];
if (!$routable && ($child = $page->children()->visible()->routable()->published()->first()) !== null) {
// Redirect to the first visible child as current page isn't routable.
$this->grav->redirectLangSafe($child->route());
}
}
// See if route matches one in the site configuration
$site_route = $config->get("site.routes.{$route}");
if ($site_route) {
$page = $this->dispatch($site_route, $all, $redirect);
} else {
/** @var Uri $uri */
$uri = $this->grav['uri'];
/** @var \Grav\Framework\Uri\Uri $source_url */
$source_url = $uri->uri(false);
if ($routable) {
return $page;
}
}
// Try Regex style redirects
$site_redirects = $config->get('site.redirects');
if (is_array($site_redirects)) {
foreach ((array)$site_redirects as $pattern => $replace) {
$pattern = ltrim($pattern, '^');
$pattern = '#^' . str_replace('/', '\/', $pattern) . '#';
try {
/** @var string $found */
$found = preg_replace($pattern, $replace, $source_url);
if ($found && $found !== $source_url) {
$this->grav->redirectLangSafe($found);
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
}
}
}
// Try Regex style routes
$site_routes = $config->get('site.routes');
if (is_array($site_routes)) {
foreach ((array)$site_routes as $pattern => $replace) {
$pattern = '#^' . str_replace('/', '\/', ltrim($pattern, '^')) . '#';
try {
/** @var string $found */
$found = preg_replace($pattern, $replace, $source_url);
if ($found && $found !== $source_url) {
$page = $this->dispatch($found, $all, $redirect);
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.routes: ' . $pattern . '-> ' . $e->getMessage());
}
}
$route = urldecode((string)$route);
// The page cannot be reached, look into site wide redirects, routes and wildcards.
$redirectedPage = $this->findSiteBasedRoute($route);
if ($redirectedPage) {
$page = $this->dispatch($redirectedPage->route(), false, $redirect);
}
/** @var Config $config */
$config = $this->grav['config'];
/** @var Uri $uri */
$uri = $this->grav['uri'];
/** @var \Grav\Framework\Uri\Uri $source_url */
$source_url = $uri->uri(false);
// Try Regex style redirects
$site_redirects = $config->get('site.redirects');
if (is_array($site_redirects)) {
foreach ((array)$site_redirects as $pattern => $replace) {
$pattern = ltrim($pattern, '^');
$pattern = '#^' . str_replace('/', '\/', $pattern) . '#';
try {
/** @var string $found */
$found = preg_replace($pattern, $replace, $source_url);
if ($found && $found !== $source_url) {
$this->grav->redirectLangSafe($found);
}
} catch (ErrorException $e) {
$this->grav['log']->error('site.redirects: ' . $pattern . '-> ' . $e->getMessage());
}
}
}
+1 -1
View File
@@ -519,7 +519,7 @@ class Uri
* Return the full uri
*
* @param bool $include_root
* @return mixed
* @return string
*/
public function uri($include_root = true)
{
+112 -33
View File
@@ -12,11 +12,15 @@ namespace Grav\Common;
use DateTime;
use DateTimeZone;
use Exception;
use Grav\Common\Flex\Types\Pages\PageObject;
use Grav\Common\Helpers\Truncator;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Markdown\Parsedown;
use Grav\Common\Markdown\ParsedownExtra;
use Grav\Common\Page\Markdown\Excerpts;
use Grav\Common\Page\Pages;
use Grav\Framework\Flex\Flex;
use Grav\Framework\Flex\Interfaces\FlexObjectInterface;
use InvalidArgumentException;
use Negotiation\Accept;
use Negotiation\Negotiator;
@@ -1520,7 +1524,7 @@ abstract class Utils
}
/**
* Get path based on a token
* Get relative page path based on a token.
*
* @param string $path
* @param PageInterface|null $page
@@ -1529,47 +1533,122 @@ abstract class Utils
*/
public static function getPagePathFromToken($path, PageInterface $page = null)
{
$path_parts = pathinfo($path);
$grav = Grav::instance();
return static::getPathFromToken($path, $page);
}
$basename = '';
if (isset($path_parts['extension'])) {
$basename = '/' . $path_parts['basename'];
$path = rtrim($path_parts['dirname'], ':');
/**
* Get relative path based on a token.
*
* Path supports following syntaxes:
*
* 'self@', 'self@/path'
* 'page@:/route', 'page@:/route/filename.ext'
* 'theme@:', 'theme@:/path'
*
* @param string $path
* @param FlexObjectInterface|PageInterface|null $object
* @return string
* @throws RuntimeException
*/
public static function getPathFromToken($path, $object = null)
{
$matches = static::resolveTokenPath($path);
if (null === $matches) {
return $path;
}
$regex = '/(@self|self@)|((?:@page|page@):(?:.*))|((?:@theme|theme@):(?:.*))/';
preg_match($regex, $path, $matches);
$grav = Grav::instance();
if ($matches) {
if ($matches[1]) {
if (null === $page) {
throw new RuntimeException('Page not available for this self@ reference');
switch ($matches[0]) {
case 'self':
if (null === $object) {
throw new RuntimeException(sprintf('Page not available for self@ reference: %s', $path));
}
} elseif ($matches[2]) {
// page@
$parts = explode(':', $path);
$route = $parts[1];
$page = $grav['page']->find($route);
} elseif ($matches[3]) {
// theme@
$parts = explode(':', $path);
$route = $parts[1];
$theme = str_replace(ROOT_DIR, '', $grav['locator']->findResource('theme://'));
return $theme . $route . $basename;
if ($matches[2] === '') {
if ($object->exists()) {
$route = '/' . $matches[1];
if ($object instanceof PageInterface) {
return trim($object->relativePagePath() . $route, '/');
}
$folder = $object->getMediaFolder();
if ($folder) {
return trim($folder . $route, '/');
}
} else {
return '';
}
}
break;
case 'page':
if ($matches[1] === '') {
$route = '/' . $matches[2];
// Exclude filename from the page lookup.
if (pathinfo($route, PATHINFO_EXTENSION)) {
$basename = '/' . basename($route);
$route = \dirname($route);
} else {
$basename = '';
}
$key = trim($route === '/' ? $grav['config']->get('system.home.alias') : $route, '/');
if ($object instanceof PageObject) {
$object = $object->getFlexDirectory()->getObject($key);
} elseif (static::isAdminPlugin()) {
/** @var Flex|null $flex */
$flex = $grav['flex'] ?? null;
$object = $flex ? $flex->getObject($key, 'pages') : null;
} else {
/** @var Pages $pages */
$pages = $grav['pages'];
$object = $pages->find($route);
}
if ($object instanceof PageInterface) {
return trim($object->relativePagePath() . $basename, '/');
}
}
break;
case 'theme':
if ($matches[1] === '') {
$route = '/' . $matches[2];
$theme = $grav['locator']->findResource('theme://', false);
if (false !== $theme) {
return trim($theme . $route, '/');
}
}
break;
}
throw new RuntimeException(sprintf('Token path not found: %s', $path));
}
/**
* Returns [token, route, path] from '@token/route:/path'. Route and path are optional. If pattern does not match, return null.
*
* @param string $path
* @return string[]|null
*/
private static function resolveTokenPath(string $path): ?array
{
if (strpos($path, '@') !== false) {
$regex = '/^(@\w+|\w+@|@\w+@)([^:]*)(.*)$/u';
if (preg_match($regex, $path, $matches)) {
return [
trim($matches[1], '@'),
trim($matches[2], '/'),
trim($matches[3], ':/')
];
}
} else {
return $path . $basename;
}
if (!$page) {
throw new RuntimeException('Page route not found: ' . $path);
}
$path = str_replace($matches[0], rtrim($page->relativePagePath(), '/'), $path);
return $path . $basename;
return null;
}
/**