Merge branch 'release/1.8.2'

This commit is contained in:
Andy Miller
2018-05-24 12:11:47 -06:00
19 changed files with 101 additions and 50 deletions

View File

@@ -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

View File

@@ -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) {

View File

@@ -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:

View File

@@ -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) {

View File

@@ -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);
}
@@ -744,7 +746,16 @@ class AdminBaseController
}
$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,6 +765,7 @@ class AdminBaseController
// Do not use self@ outside of pages
if ($this->view !== 'pages' && in_array($folder, ['@self', 'self@', '@self@'])) {
if (!$data instanceof MediaInterface) {
$this->admin->json_response = [
'status' => 'error',
'message' => sprintf($this->admin->translate('PLUGIN_ADMIN.FILEUPLOAD_PREVENT_SELF', null), $folder)
@@ -762,11 +774,15 @@ class AdminBaseController
return false;
}
$media = $data->getMedia();
} else {
// Set destination
$folder = Folder::getRelativePath(rtrim($folder, '/'));
$folder = $this->admin->getPagePathFromToken($folder);
$media = new Media($folder);
}
$available_files = [];
$metadata = [];
$thumbs = [];

View File

@@ -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;

View File

@@ -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"

View File

@@ -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;

View File

@@ -162,7 +162,6 @@ export default class FilesField {
}
getURI() {
console.log(this.container.data('mediaUri'));
return this.container.data('mediaUri') || '';
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -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 {

View File

@@ -604,7 +604,7 @@ textarea.frontmatter {
letter-spacing: normal;
}
.form-fieldset {
margin: 1rem 2rem;
margin: 1rem 1.5rem;
}
.form-fieldset--label {

View File

@@ -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' : '' }}">
<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 %}

View File

@@ -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>

View File

@@ -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">