mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-05 04:46:03 +01:00
Merge branch 'release/1.8.2'
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -1,3 +1,19 @@
|
||||
# v1.8.2
|
||||
## 05/24/2018
|
||||
|
||||
1. [](#new)
|
||||
* Added custom object support for filepicker field
|
||||
* Don't allow saving of a user with no local account file
|
||||
* Controls for `list` field were not in sync between top and bottom
|
||||
1. [](#improved)
|
||||
* More subtle `fieldset` styling
|
||||
1. [](#bugfix)
|
||||
* Check if `$object->blueprints()` exists in `onAdminAfterSave`
|
||||
* When creating first user, check `admin.login` not `site.login`
|
||||
* Fix admin login redirects for multisite setups
|
||||
* Fixed issue with filepicker field where images wouldn't properly merge with the current value if in a page header
|
||||
* Fixed media delete for streams
|
||||
|
||||
# v1.8.1
|
||||
## 05/15/2018
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ class AdminPlugin extends Plugin
|
||||
unset($this->grav['user']);
|
||||
$this->grav['user'] = $user;
|
||||
$user->authenticated = true;
|
||||
$user->authorized = $user->authorize('site.login');
|
||||
$user->authorized = $user->authorize('admin.login');
|
||||
|
||||
$messages = $this->grav['messages'];
|
||||
$messages->add($this->grav['language']->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN'), 'info');
|
||||
@@ -456,7 +456,9 @@ class AdminPlugin extends Plugin
|
||||
$twig->twig_vars['location'] = $this->template;
|
||||
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'] ?: '/';
|
||||
$twig->twig_vars['admin_route'] = trim($this->admin_route, '/');
|
||||
$twig->twig_vars['current_route'] = '/' . $twig->twig_vars['admin_route'] . '/' . $this->template . '/' . $this->route;
|
||||
$twig->twig_vars['base_url_relative'] = $twig->twig_vars['base_url_simple'] . '/' . $twig->twig_vars['admin_route'];
|
||||
$twig->twig_vars['current_url'] = rtrim($twig->twig_vars['base_url_relative'] . '/' . $this->template . '/' . $this->route, '/');
|
||||
$theme_url = '/' . ltrim($this->grav['locator']->findResource('plugin://admin/themes/' . $this->theme,
|
||||
false), '/');
|
||||
$twig->twig_vars['theme_url'] = $theme_url;
|
||||
@@ -762,7 +764,8 @@ class AdminPlugin extends Plugin
|
||||
{
|
||||
// Special case to redirect after changing the admin route to avoid 'breaking'
|
||||
$obj = $event['object'];
|
||||
if (null !== $obj) {
|
||||
|
||||
if (null !== $obj && method_exists($obj, 'blueprints')) {
|
||||
$blueprint = $obj->blueprints()->getFilename();
|
||||
|
||||
if ($blueprint === 'admin/blueprints' && isset($obj->route) && $this->admin_route !== $obj->route) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: Admin Panel
|
||||
version: 1.8.1
|
||||
version: 1.8.2
|
||||
description: Adds an advanced administration panel to manage your site
|
||||
icon: empire
|
||||
author:
|
||||
|
||||
@@ -365,7 +365,7 @@ class Admin
|
||||
|
||||
$userKey = isset($credentials['username']) ? (string)$credentials['username'] : '';
|
||||
$ipKey = Uri::ip();
|
||||
$redirect = isset($post['redirect']) ? $post['redirect'] : $this->uri->route();
|
||||
$redirect = $this->base . $this->route;
|
||||
|
||||
// Check if the current IP has been used in failed login attempts.
|
||||
$attempts = count($rateLimiter->getAttempts($ipKey, 'ip'));
|
||||
@@ -392,11 +392,9 @@ class Admin
|
||||
if ($user->authorized) {
|
||||
$event->defMessage('PLUGIN_ADMIN.LOGIN_LOGGED_IN', 'info');
|
||||
|
||||
$event->defRedirect($redirect);
|
||||
$event->defRedirect(isset($post['redirect']) ? $post['redirect'] : $redirect);
|
||||
} else {
|
||||
$this->session->redirect = $redirect;
|
||||
|
||||
$event->defRedirect($this->uri->route());
|
||||
}
|
||||
} else {
|
||||
if ($user->authorized) {
|
||||
@@ -406,7 +404,7 @@ class Admin
|
||||
}
|
||||
}
|
||||
|
||||
$event->defRedirect($this->uri->route());
|
||||
$event->defRedirect($redirect);
|
||||
|
||||
$message = $event->getMessage();
|
||||
if ($message) {
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
namespace Grav\Plugin\Admin;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaInterface;
|
||||
use Grav\Common\Page\Media;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Plugin;
|
||||
@@ -259,7 +261,7 @@ class AdminBaseController
|
||||
}
|
||||
|
||||
// Handle errors and breaks without proceeding further
|
||||
if ($upload->file->error != UPLOAD_ERR_OK) {
|
||||
if ($upload->file->error !== UPLOAD_ERR_OK) {
|
||||
$this->admin->json_response = [
|
||||
'status' => 'error',
|
||||
'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_UNABLE_TO_UPLOAD', null),
|
||||
@@ -717,9 +719,9 @@ class AdminBaseController
|
||||
} else {
|
||||
$new_data = $files;
|
||||
}
|
||||
if (isset($data['header'][$init_key])) {
|
||||
if ($obj->header()->{$init_key}) {
|
||||
$obj->modifyHeader($init_key,
|
||||
array_replace_recursive([], $data['header'][$init_key], $new_data));
|
||||
array_replace_recursive([], $obj->header()->{$init_key}, $new_data));
|
||||
} else {
|
||||
$obj->modifyHeader($init_key, $new_data);
|
||||
}
|
||||
@@ -743,8 +745,17 @@ class AdminBaseController
|
||||
return false;
|
||||
}
|
||||
|
||||
$data = $this->view === 'pages' ? $this->admin->page(true) : $this->prepareData([]);
|
||||
$settings = $data->blueprints()->schema()->getProperty($this->post['name']);
|
||||
$data = $this->view === 'pages' ? $this->admin->page(true) : $this->prepareData([]);
|
||||
|
||||
if (null === $data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($data instanceof Data) {
|
||||
$settings = $data->blueprints()->schema()->getProperty($this->post['name']);
|
||||
} elseif (method_exists($data, 'getBlueprint')) {
|
||||
$settings = $data->getBlueprint()->schema()->getProperty($this->post['name']);
|
||||
}
|
||||
|
||||
if (isset($settings['folder'])) {
|
||||
$folder = $settings['folder'];
|
||||
@@ -754,19 +765,24 @@ class AdminBaseController
|
||||
|
||||
// Do not use self@ outside of pages
|
||||
if ($this->view !== 'pages' && in_array($folder, ['@self', 'self@', '@self@'])) {
|
||||
$this->admin->json_response = [
|
||||
'status' => 'error',
|
||||
'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_PREVENT_SELF', null), $folder)
|
||||
];
|
||||
if (!$data instanceof MediaInterface) {
|
||||
$this->admin->json_response = [
|
||||
'status' => 'error',
|
||||
'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_PREVENT_SELF', null), $folder)
|
||||
];
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
$media = $data->getMedia();
|
||||
} else {
|
||||
// Set destination
|
||||
$folder = Folder::getRelativePath(rtrim($folder, '/'));
|
||||
$folder = $this->admin->getPagePathFromToken($folder);
|
||||
|
||||
$media = new Media($folder);
|
||||
}
|
||||
|
||||
// Set destination
|
||||
$folder = Folder::getRelativePath(rtrim($folder, '/'));
|
||||
$folder = $this->admin->getPagePathFromToken($folder);
|
||||
|
||||
$media = new Media($folder);
|
||||
$available_files = [];
|
||||
$metadata = [];
|
||||
$thumbs = [];
|
||||
|
||||
@@ -613,12 +613,14 @@ class AdminController extends AdminBaseController
|
||||
|
||||
// Special handler for user data.
|
||||
if ($this->view === 'user') {
|
||||
if (!$this->grav['user']->exists()) {
|
||||
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.NO_USER_EXISTS'),'error');
|
||||
return false;
|
||||
}
|
||||
if (!$this->admin->authorize(['admin.super', 'admin.users'])) {
|
||||
//not admin.super or admin.users
|
||||
// no user file or not admin.super or admin.users
|
||||
if ($this->prepareData($data)->username !== $this->grav['user']->username) {
|
||||
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.',
|
||||
'error');
|
||||
|
||||
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.INSUFFICIENT_PERMISSIONS_FOR_TASK') . ' save.','error');
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1687,9 +1689,16 @@ class AdminController extends AdminBaseController
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
$path = $media->path();
|
||||
if ($locator->isStream($path)) {
|
||||
$path = $locator->findResource($path, true, true);
|
||||
}
|
||||
|
||||
// Upload it
|
||||
if (!move_uploaded_file($_FILES['file']['tmp_name'],
|
||||
sprintf('%s/%s', $media->path(), $_FILES['file']['name']))
|
||||
sprintf('%s/%s', $path, $_FILES['file']['name']))
|
||||
) {
|
||||
$this->admin->json_response = [
|
||||
'status' => 'error',
|
||||
@@ -1759,7 +1768,13 @@ class AdminController extends AdminBaseController
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = $this->grav['locator'];
|
||||
|
||||
$targetPath = $media->path() . '/' . $filename;
|
||||
if ($locator->isStream($targetPath)) {
|
||||
$targetPath = $locator->findResource($targetPath, true, true);
|
||||
}
|
||||
$fileParts = pathinfo($filename);
|
||||
|
||||
$found = false;
|
||||
|
||||
@@ -441,6 +441,7 @@ PLUGIN_ADMIN:
|
||||
PAGE_FILE: "Page Template"
|
||||
PAGE_FILE_HELP: "Page template file name, and by default the display template for this page"
|
||||
NO_USER_ACCOUNTS: "No user accounts found, please create one first..."
|
||||
NO_USER_EXISTS: "No local user exists for this account, cannot save..."
|
||||
REDIRECT_TRAILING_SLASH: "Redirect trailing slash"
|
||||
REDIRECT_TRAILING_SLASH_HELP: "Perform a 301 redirect rather than transparently handling trailing slash URIs."
|
||||
DEFAULT_DATE_FORMAT: "Page date format"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import $ from 'jquery';
|
||||
import { config } from 'grav-config';
|
||||
import { config, uri_params } from 'grav-config';
|
||||
import request from '../../utils/request';
|
||||
|
||||
const insertTextAt = (string, index, text) => [string.slice(0, index), text, string.slice(index)].join('');
|
||||
@@ -45,10 +45,11 @@ export default class FilePickerField {
|
||||
let parent = field.closest('[data-grav-filepicker]');
|
||||
let name = parent.data('name');
|
||||
let value = parent.data('value');
|
||||
let params = JSON.stringify(uri_params || '{}');
|
||||
|
||||
request(url, {
|
||||
method: 'post',
|
||||
body: { name }
|
||||
body: { name, params }
|
||||
}, (response) => {
|
||||
if (typeof response.files === 'undefined') {
|
||||
return;
|
||||
|
||||
@@ -162,7 +162,6 @@ export default class FilesField {
|
||||
}
|
||||
|
||||
getURI() {
|
||||
console.log(this.container.data('mediaUri'));
|
||||
return this.container.data('mediaUri') || '';
|
||||
}
|
||||
|
||||
|
||||
2
themes/grav/css-compiled/preset.css
vendored
2
themes/grav/css-compiled/preset.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
themes/grav/css-compiled/template.css
vendored
2
themes/grav/css-compiled/template.css
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
themes/grav/js/admin.min.js
vendored
4
themes/grav/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -909,16 +909,16 @@ form {
|
||||
}
|
||||
|
||||
.form-fieldset {
|
||||
background-color: #f7f7f7;
|
||||
border: 2px solid #e1e1e1;
|
||||
background-color: darken($content-bg, 1%);
|
||||
border: 1px solid $form-border;
|
||||
}
|
||||
|
||||
.form-fieldset--label {
|
||||
background-color: #f3f3f3;
|
||||
background-color: darken($content-bg, 4%);
|
||||
|
||||
&:hover,
|
||||
.form-fieldset input:checked + & {
|
||||
background-color: #eee;
|
||||
background-color: darken($content-bg, 6%);
|
||||
}
|
||||
}
|
||||
#admin-main {
|
||||
|
||||
@@ -604,7 +604,7 @@ textarea.frontmatter {
|
||||
letter-spacing: normal;
|
||||
}
|
||||
.form-fieldset {
|
||||
margin: 1rem 2rem;
|
||||
margin: 1rem 1.5rem;
|
||||
}
|
||||
|
||||
.form-fieldset--label {
|
||||
|
||||
@@ -45,16 +45,18 @@
|
||||
{% if field.max is defined and not field.selectunique %}data-max="{{ field.max }}"{% endif %}
|
||||
>
|
||||
{% if fieldControls in ['top', 'both'] %}
|
||||
<div class="collection-actions{{ not value|length ? ' hidden' : '' }}">
|
||||
<button class="button" type="button" data-action="expand_all"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-down"></i> {{ "PLUGIN_ADMIN.EXPAND_ALL"|e|tu }}</button>
|
||||
<button class="button" type="button" data-action="collapse_all"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-right"></i> {{ "PLUGIN_ADMIN.COLLAPSE_ALL"|e|tu }}</button>
|
||||
<div class="collection-actions">
|
||||
{% if collapsible %}
|
||||
<button class="button" type="button" data-action="expand_all"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-down"></i> {{ "PLUGIN_ADMIN.EXPAND_ALL"|e|tu }}</button>
|
||||
<button class="button" type="button" data-action="collapse_all"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-chevron-circle-right"></i> {{ "PLUGIN_ADMIN.COLLAPSE_ALL"|e|tu }}</button>
|
||||
{% endif %}
|
||||
{% if field.sortby %}
|
||||
<button class="button{{ not value|length ? ' hidden' : '' }}" type="button" data-action="sort" data-action-sort="{{ field.sortby }}" data-action-sort-dir="{{ field.sortby_dir|default('asc') }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-sort-amount-{{ field.sortby_dir|default('asc') }}"></i> {{ btnSortLabel|e|tu }} '{{ field.sortby }}'</button>
|
||||
{% endif %}
|
||||
<button class="button" type="button" data-action="add" data-action-add="top"
|
||||
<button class="button" type="button" data-action="add" data-action-add="bottom"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}><i class="fa fa-plus"></i> {{ btnLabel|e|tu }}</button>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{% if authorize(['admin.pages', 'admin.super']) %}
|
||||
<div id="latest">
|
||||
<div class="button-bar">
|
||||
<a class="button" href="{{ uri.route(true) }}/pages"><i class="fa fa-fw fa-file-text-o"></i>{{ "PLUGIN_ADMIN.MANAGE_PAGES"|tu }}</a>
|
||||
<a class="button" href="{{ base_url_relative }}/pages"><i class="fa fa-fw fa-file-text-o"></i>{{ "PLUGIN_ADMIN.MANAGE_PAGES"|tu }}</a>
|
||||
</div>
|
||||
<h1>{{ "PLUGIN_ADMIN.LATEST_PAGE_UPDATES"|tu }}</h1>
|
||||
<table>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
{% block integration %}{% endblock %}
|
||||
|
||||
{% set redirect = redirect ?: uri.route(false) %}
|
||||
{% set redirect = redirect ?: '/' ~ admin_route ~ '/' ~ admin.route %}
|
||||
|
||||
<form method="post" action="{{ base_url_relative }}">
|
||||
<div class="padding">
|
||||
|
||||
Reference in New Issue
Block a user