mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-01 19:06:16 +01:00
Merge branch 'develop' into feature/new-folder-modal
This commit is contained in:
19
CHANGELOG.md
19
CHANGELOG.md
@@ -1,3 +1,22 @@
|
|||||||
|
# v1.0.7
|
||||||
|
## 01/15/2016
|
||||||
|
|
||||||
|
1. [](#new)
|
||||||
|
* Added onAdminDashboard event
|
||||||
|
* Added onAdminSave event
|
||||||
|
* New lang strings for reverse proxy toggle
|
||||||
|
1. [](#improved)
|
||||||
|
* More robust YAML file checking in config folders
|
||||||
|
* Removed deprecated menu event
|
||||||
|
* Removed old logs code
|
||||||
|
* Used new onAdminDashboard event for current dashboard widgets
|
||||||
|
1. [](#bugfix)
|
||||||
|
* Fix for missing access checks on config pages #397
|
||||||
|
* Fix parent not loaded on admin form save #587
|
||||||
|
* When no route field is added to a page blueprint, add it as page root
|
||||||
|
* Fix for wrong page count (will show dynamic added pages in count too - Need to fix this)
|
||||||
|
* Fix for IE/Edge saving forms #391
|
||||||
|
|
||||||
# v1.0.6
|
# v1.0.6
|
||||||
## 01/07/2016
|
## 01/07/2016
|
||||||
|
|
||||||
|
|||||||
47
admin.php
47
admin.php
@@ -17,6 +17,10 @@ use RocketTheme\Toolbox\Session\Session;
|
|||||||
|
|
||||||
class AdminPlugin extends Plugin
|
class AdminPlugin extends Plugin
|
||||||
{
|
{
|
||||||
|
public $features = [
|
||||||
|
'blueprints' => 1000,
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
@@ -96,10 +100,10 @@ class AdminPlugin extends Plugin
|
|||||||
|
|
||||||
// check for existence of a user account
|
// check for existence of a user account
|
||||||
$account_dir = $file_path = $this->grav['locator']->findResource('account://');
|
$account_dir = $file_path = $this->grav['locator']->findResource('account://');
|
||||||
$user_check = (array) glob($account_dir . '/*.yaml');
|
$user_check = glob($account_dir . '/*.yaml');
|
||||||
|
|
||||||
// If no users found, go to register
|
// If no users found, go to register
|
||||||
if (!count($user_check) > 0) {
|
if ($user_check == false || count((array)$user_check) == 0) {
|
||||||
if (!$this->isAdminPath()) {
|
if (!$this->isAdminPath()) {
|
||||||
$this->grav->redirect($this->base);
|
$this->grav->redirect($this->base);
|
||||||
}
|
}
|
||||||
@@ -119,12 +123,11 @@ class AdminPlugin extends Plugin
|
|||||||
* - 'password1' for password format
|
* - 'password1' for password format
|
||||||
* - 'password2' for equality to password1
|
* - 'password2' for equality to password1
|
||||||
*
|
*
|
||||||
* @param object $form The form
|
|
||||||
* @param string $type The field type
|
* @param string $type The field type
|
||||||
* @param string $value The field value
|
* @param string $value The field value
|
||||||
* @param string $extra Any extra value required
|
* @param string $extra Any extra value required
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function validate($type, $value, $extra = '')
|
protected function validate($type, $value, $extra = '')
|
||||||
{
|
{
|
||||||
@@ -134,22 +137,21 @@ class AdminPlugin extends Plugin
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
|
|
||||||
case 'password1':
|
case 'password1':
|
||||||
if (!preg_match('/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/', $value)) {
|
if (!preg_match('/(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}/', $value)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
|
|
||||||
case 'password2':
|
case 'password2':
|
||||||
if (strcmp($value, $extra)) {
|
if (strcmp($value, $extra)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -255,7 +257,7 @@ class AdminPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace themes service with admin.
|
// Replace themes service with admin.
|
||||||
$this->grav['themes'] = function ($c) {
|
$this->grav['themes'] = function () {
|
||||||
require_once __DIR__ . '/classes/themes.php';
|
require_once __DIR__ . '/classes/themes.php';
|
||||||
return new Themes($this->grav);
|
return new Themes($this->grav);
|
||||||
};
|
};
|
||||||
@@ -328,6 +330,8 @@ class AdminPlugin extends Plugin
|
|||||||
// make sure page is not frozen!
|
// make sure page is not frozen!
|
||||||
unset($this->grav['page']);
|
unset($this->grav['page']);
|
||||||
|
|
||||||
|
$this->admin->pagesCount();
|
||||||
|
|
||||||
// Replace page service with admin.
|
// Replace page service with admin.
|
||||||
$this->grav['page'] = function () use ($self) {
|
$this->grav['page'] = function () use ($self) {
|
||||||
$page = new Page;
|
$page = new Page;
|
||||||
@@ -352,6 +356,8 @@ class AdminPlugin extends Plugin
|
|||||||
return $page;
|
return $page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (empty($this->grav['page'])) {
|
if (empty($this->grav['page'])) {
|
||||||
@@ -405,16 +411,12 @@ class AdminPlugin extends Plugin
|
|||||||
{
|
{
|
||||||
$twig = $this->grav['twig'];
|
$twig = $this->grav['twig'];
|
||||||
|
|
||||||
// Dynamic type support
|
|
||||||
$format = $this->uri->extension();
|
|
||||||
$ext = '.' . ($format ? $format : 'html') . TWIG_EXT;
|
|
||||||
|
|
||||||
$twig->twig_vars['location'] = $this->template;
|
$twig->twig_vars['location'] = $this->template;
|
||||||
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'] ?: '/';
|
$twig->twig_vars['base_url_relative_frontend'] = $twig->twig_vars['base_url_relative'] ?: '/';
|
||||||
$twig->twig_vars['admin_route'] = trim($this->config->get('plugins.admin.route'), '/');
|
$twig->twig_vars['admin_route'] = trim($this->config->get('plugins.admin.route'), '/');
|
||||||
$twig->twig_vars['base_url_relative'] =
|
$twig->twig_vars['base_url_relative'] =
|
||||||
$twig->twig_vars['base_url_simple'] . '/' . $twig->twig_vars['admin_route'];
|
$twig->twig_vars['base_url_simple'] . '/' . $twig->twig_vars['admin_route'];
|
||||||
$twig->twig_vars['theme_url'] = '/user/plugins/admin/themes/' . $this->theme;
|
$twig->twig_vars['theme_url'] = $this->grav['locator']->findResource('plugin://admin/themes/' . $this->theme, false);
|
||||||
$twig->twig_vars['base_url'] = $twig->twig_vars['base_url_relative'];
|
$twig->twig_vars['base_url'] = $twig->twig_vars['base_url_relative'];
|
||||||
$twig->twig_vars['base_path'] = GRAV_ROOT;
|
$twig->twig_vars['base_path'] = GRAV_ROOT;
|
||||||
$twig->twig_vars['admin'] = $this->admin;
|
$twig->twig_vars['admin'] = $this->admin;
|
||||||
@@ -538,15 +540,6 @@ class AdminPlugin extends Plugin
|
|||||||
throw new \RuntimeException('One of the required plugins is missing or not enabled');
|
throw new \RuntimeException('One of the required plugins is missing or not enabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Double check we have system.yaml and site.yaml
|
|
||||||
$config_files[] = $this->grav['locator']->findResource('user://config') . '/system.yaml';
|
|
||||||
$config_files[] = $this->grav['locator']->findResource('user://config') . '/site.yaml';
|
|
||||||
foreach ($config_files as $config_file) {
|
|
||||||
if (!file_exists($config_file)) {
|
|
||||||
touch($config_file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize Admin Language if needed
|
// Initialize Admin Language if needed
|
||||||
/** @var Language $language */
|
/** @var Language $language */
|
||||||
$language = $this->grav['language'];
|
$language = $this->grav['language'];
|
||||||
@@ -570,9 +563,19 @@ class AdminPlugin extends Plugin
|
|||||||
|
|
||||||
$this->admin = new Admin($this->grav, $this->base, $this->template, $this->route);
|
$this->admin = new Admin($this->grav, $this->base, $this->template, $this->route);
|
||||||
|
|
||||||
|
|
||||||
// And store the class into DI container.
|
// And store the class into DI container.
|
||||||
$this->grav['admin'] = $this->admin;
|
$this->grav['admin'] = $this->admin;
|
||||||
|
|
||||||
|
// Double check we have system.yam, site.yaml etc
|
||||||
|
$config_path = $this->grav['locator']->findResource('user://config');
|
||||||
|
foreach ($this->admin->configurations() as $config_file) {
|
||||||
|
$config_file = "{$config_path}/{$config_file}.yaml";
|
||||||
|
if (!file_exists($config_file)) {
|
||||||
|
touch($config_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get theme for admin
|
// Get theme for admin
|
||||||
$this->theme = $this->config->get('plugins.admin.theme', 'grav');
|
$this->theme = $this->config->get('plugins.admin.theme', 'grav');
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: Admin Panel
|
name: Admin Panel
|
||||||
version: 1.0.6
|
version: 1.0.7
|
||||||
description: Adds an advanced administration panel to manage your site
|
description: Adds an advanced administration panel to manage your site
|
||||||
icon: empire
|
icon: empire
|
||||||
author:
|
author:
|
||||||
@@ -27,12 +27,12 @@ form:
|
|||||||
|
|
||||||
enabled:
|
enabled:
|
||||||
type: hidden
|
type: hidden
|
||||||
label: Plugin status
|
label: PLUGIN_ADMIN.PLUGIN_STATUS
|
||||||
highlight: 1
|
highlight: 1
|
||||||
default: 0
|
default: 0
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
|
|
||||||
@@ -64,8 +64,8 @@ form:
|
|||||||
highlight: 1
|
highlight: 1
|
||||||
default: 1
|
default: 1
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
help: Use Google custom fonts. Disable this to use Helvetica. Useful when using Cyrillic and other languages with unsupported characters.
|
help: Use Google custom fonts. Disable this to use Helvetica. Useful when using Cyrillic and other languages with unsupported characters.
|
||||||
@@ -79,8 +79,8 @@ form:
|
|||||||
highlight: 1
|
highlight: 1
|
||||||
default: 1
|
default: 1
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
help: Show the "Found an issue? Please report it on GitHub." message.
|
help: Show the "Found an issue? Please report it on GitHub." message.
|
||||||
@@ -91,8 +91,8 @@ form:
|
|||||||
highlight: 1
|
highlight: 1
|
||||||
default: 1
|
default: 1
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
help: Shows an informative message, in the admin panel, when an update is available.
|
help: Shows an informative message, in the admin panel, when an update is available.
|
||||||
@@ -112,8 +112,8 @@ form:
|
|||||||
highlight: 1
|
highlight: 1
|
||||||
default: 1
|
default: 1
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
help: Ask the user confirmation when deleting a page
|
help: Ask the user confirmation when deleting a page
|
||||||
@@ -129,8 +129,8 @@ form:
|
|||||||
highlight: 1
|
highlight: 1
|
||||||
default: 1
|
default: 1
|
||||||
options:
|
options:
|
||||||
1: Enabled
|
1: PLUGIN_ADMIN.ENABLED
|
||||||
0: Disabled
|
0: PLUGIN_ADMIN.DISABLED
|
||||||
validate:
|
validate:
|
||||||
type: bool
|
type: bool
|
||||||
help: Enable the visitors stats collecting feature
|
help: Enable the visitors stats collecting feature
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ use Grav\Common\User\User;
|
|||||||
use Grav\Common\Utils;
|
use Grav\Common\Utils;
|
||||||
use RocketTheme\Toolbox\File\File;
|
use RocketTheme\Toolbox\File\File;
|
||||||
use RocketTheme\Toolbox\File\JsonFile;
|
use RocketTheme\Toolbox\File\JsonFile;
|
||||||
use RocketTheme\Toolbox\File\LogFile;
|
use RocketTheme\Toolbox\ResourceLocator\UniformResourceIterator;
|
||||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||||
use RocketTheme\Toolbox\Session\Message;
|
use RocketTheme\Toolbox\Session\Message;
|
||||||
use RocketTheme\Toolbox\Session\Session;
|
use RocketTheme\Toolbox\Session\Session;
|
||||||
@@ -71,15 +71,15 @@ class Admin
|
|||||||
public $user;
|
public $user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Lang
|
* @var GPM
|
||||||
*/
|
|
||||||
protected $lang;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var Grav\Common\GPM\GPM
|
|
||||||
*/
|
*/
|
||||||
protected $gpm;
|
protected $gpm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
protected $pages_count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
@@ -184,8 +184,7 @@ class Admin
|
|||||||
/** @var Grav $grav */
|
/** @var Grav $grav */
|
||||||
$grav = $this->grav;
|
$grav = $this->grav;
|
||||||
|
|
||||||
$this->setMessage($this->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN', [$this->user->language]), 'info');
|
$this->setMessage($this->translate('PLUGIN_ADMIN.LOGIN_LOGGED_IN'), 'info');
|
||||||
|
|
||||||
$redirect_route = $this->uri->route();
|
$redirect_route = $this->uri->route();
|
||||||
$grav->redirect($redirect_route);
|
$grav->redirect($redirect_route);
|
||||||
}
|
}
|
||||||
@@ -340,9 +339,12 @@ class Admin
|
|||||||
$type = preg_replace('|config/|', '', $type);
|
$type = preg_replace('|config/|', '', $type);
|
||||||
$blueprints = $this->blueprints("config/{$type}");
|
$blueprints = $this->blueprints("config/{$type}");
|
||||||
$config = $this->grav['config'];
|
$config = $this->grav['config'];
|
||||||
$obj = new Data\Data($config->get($type), $blueprints);
|
$obj = new Data\Data($config->get($type, []), $blueprints);
|
||||||
$obj->merge($post);
|
$obj->merge($post);
|
||||||
$file = CompiledYamlFile::instance($this->grav['locator']->findResource("config://{$type}.yaml"));
|
// FIXME: We shouldn't allow user to change configuration files in system folder!
|
||||||
|
$filename = $this->grav['locator']->findResource("config://{$type}.yaml")
|
||||||
|
?: $this->grav['locator']->findResource("config://{$type}.yaml", true, true);
|
||||||
|
$file = CompiledYamlFile::instance($filename);
|
||||||
$obj->file($file);
|
$obj->file($file);
|
||||||
$data[$type] = $obj;
|
$data[$type] = $obj;
|
||||||
} else {
|
} else {
|
||||||
@@ -386,6 +388,8 @@ class Admin
|
|||||||
/**
|
/**
|
||||||
* Get all routes.
|
* Get all routes.
|
||||||
*
|
*
|
||||||
|
* @param bool $unique
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function routes($unique = false)
|
public function routes($unique = false)
|
||||||
@@ -406,12 +410,13 @@ class Admin
|
|||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function countPages()
|
public function pagesCount()
|
||||||
{
|
{
|
||||||
$routable = $this->grav['pages']->all()->routable();
|
if (!$this->pages_count) {
|
||||||
$modular = $this->grav['pages']->all()->modular();
|
$this->pages_count = count($this->grav['pages']->all());
|
||||||
|
}
|
||||||
|
|
||||||
return count($routable) + count($modular);
|
return $this->pages_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -451,6 +456,8 @@ class Admin
|
|||||||
/**
|
/**
|
||||||
* Get all plugins.
|
* Get all plugins.
|
||||||
*
|
*
|
||||||
|
* @param bool $local
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function plugins($local = true)
|
public function plugins($local = true)
|
||||||
@@ -458,7 +465,7 @@ class Admin
|
|||||||
$gpm = $this->gpm();
|
$gpm = $this->gpm();
|
||||||
|
|
||||||
if (!$gpm) {
|
if (!$gpm) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $local ? $gpm->getInstalledPlugins() : $gpm->getRepositoryPlugins()->filter(function (
|
return $local ? $gpm->getInstalledPlugins() : $gpm->getRepositoryPlugins()->filter(function (
|
||||||
@@ -472,6 +479,8 @@ class Admin
|
|||||||
/**
|
/**
|
||||||
* Get all themes.
|
* Get all themes.
|
||||||
*
|
*
|
||||||
|
* @param bool $local
|
||||||
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function themes($local = true)
|
public function themes($local = true)
|
||||||
@@ -479,7 +488,7 @@ class Admin
|
|||||||
$gpm = $this->gpm();
|
$gpm = $this->gpm();
|
||||||
|
|
||||||
if (!$gpm) {
|
if (!$gpm) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $local ? $gpm->getInstalledThemes() : $gpm->getRepositoryThemes()->filter(function ($package, $slug) use
|
return $local ? $gpm->getInstalledThemes() : $gpm->getRepositoryThemes()->filter(function ($package, $slug) use
|
||||||
@@ -496,7 +505,7 @@ class Admin
|
|||||||
*
|
*
|
||||||
* @param integer $count number of pages to pull back
|
* @param integer $count number of pages to pull back
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array|null
|
||||||
*/
|
*/
|
||||||
public function latestPages($count = 10)
|
public function latestPages($count = 10)
|
||||||
{
|
{
|
||||||
@@ -506,7 +515,7 @@ class Admin
|
|||||||
$latest = array();
|
$latest = array();
|
||||||
|
|
||||||
if(is_null($pages->routes())){
|
if(is_null($pages->routes())){
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($pages->routes() as $url => $path) {
|
foreach ($pages->routes() as $url => $path) {
|
||||||
@@ -698,18 +707,19 @@ class Admin
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the configuration files found
|
* Return the found configuration blueprints
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public static function configurations()
|
public static function configurations()
|
||||||
{
|
{
|
||||||
$configurations = [];
|
$configurations = [];
|
||||||
$path = Grav::instance()['locator']->findResource('user://config');
|
|
||||||
|
|
||||||
/** @var \DirectoryIterator $directory */
|
/** @var UniformResourceIterator $iterator */
|
||||||
foreach (new \DirectoryIterator($path) as $file) {
|
$iterator = Grav::instance()['locator']->getIterator('blueprints://config');
|
||||||
if ($file->isDir() || $file->isDot() || !preg_match('/^[^.].*.yaml$/', $file->getFilename())) {
|
|
||||||
|
foreach ($iterator as $file) {
|
||||||
|
if ($file->isDir() || !preg_match('/^[^.].*.yaml$/', $file->getFilename())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$configurations[] = basename($file->getBasename(), '.yaml');
|
$configurations[] = basename($file->getBasename(), '.yaml');
|
||||||
@@ -744,6 +754,7 @@ class Admin
|
|||||||
$pages = Grav::instance()['pages'];
|
$pages = Grav::instance()['pages'];
|
||||||
$route = '/' . ltrim(Grav::instance()['admin']->route, '/');
|
$route = '/' . ltrim(Grav::instance()['admin']->route, '/');
|
||||||
|
|
||||||
|
/** @var Page $page */
|
||||||
$page = $pages->dispatch($route);
|
$page = $pages->dispatch($route);
|
||||||
$parent_route = null;
|
$parent_route = null;
|
||||||
if ($page) {
|
if ($page) {
|
||||||
@@ -824,14 +835,11 @@ class Admin
|
|||||||
/**
|
/**
|
||||||
* Translate a string to the user-defined language
|
* Translate a string to the user-defined language
|
||||||
*
|
*
|
||||||
* @param $string the string to translate
|
* @param array|mixed $args
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function translate($string)
|
public function translate($args)
|
||||||
{
|
|
||||||
return $this->_translate($string, [$this->grav['user']->authenticated ? $this->grav['user']->language : 'en']);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function _translate($args, Array $languages = null, $array_support = false, $html_out = false)
|
|
||||||
{
|
{
|
||||||
if (is_array($args)) {
|
if (is_array($args)) {
|
||||||
$lookup = array_shift($args);
|
$lookup = array_shift($args);
|
||||||
@@ -840,6 +848,8 @@ class Admin
|
|||||||
$args = [];
|
$args = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$languages = [$this->grav['user']->authenticated ? $this->grav['user']->language : 'en'];
|
||||||
|
|
||||||
if ($lookup) {
|
if ($lookup) {
|
||||||
if (empty($languages) || reset($languages) == null) {
|
if (empty($languages) || reset($languages) == null) {
|
||||||
if ($this->grav['config']->get('system.languages.translations_fallback', true)) {
|
if ($this->grav['config']->get('system.languages.translations_fallback', true)) {
|
||||||
@@ -848,22 +858,19 @@ class Admin
|
|||||||
$languages = (array)$this->grav['language']->getDefault();
|
$languages = (array)$this->grav['language']->getDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
$languages = ['en'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach ((array)$languages as $lang) {
|
foreach ((array)$languages as $lang) {
|
||||||
$translation = $this->grav['language']->getTranslation($lang, $lookup, $array_support);
|
$translation = $this->grav['language']->getTranslation($lang, $lookup);
|
||||||
|
|
||||||
if (!$translation) {
|
if (!$translation) {
|
||||||
$language = $this->grav['language']->getDefault() ?: 'en';
|
$language = $this->grav['language']->getDefault() ?: 'en';
|
||||||
$translation = $this->grav['language']->getTranslation($language, $lookup, $array_support);
|
$translation = $this->grav['language']->getTranslation($language, $lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$translation) {
|
if (!$translation) {
|
||||||
$language = 'en';
|
$language = 'en';
|
||||||
$translation = $this->grav['language']->getTranslation($language, $lookup, $array_support);
|
$translation = $this->grav['language']->getTranslation($language, $lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($translation) {
|
if ($translation) {
|
||||||
@@ -878,6 +885,10 @@ class Admin
|
|||||||
return $lookup;
|
return $lookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $php_format
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
function dateformat2Kendo($php_format)
|
function dateformat2Kendo($php_format)
|
||||||
{
|
{
|
||||||
$SYMBOLS_MATCHING = array(
|
$SYMBOLS_MATCHING = array(
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use Grav\Common\GPM\Installer;
|
|||||||
use Grav\Common\Grav;
|
use Grav\Common\Grav;
|
||||||
use Grav\Common\Uri;
|
use Grav\Common\Uri;
|
||||||
use Grav\Common\Data;
|
use Grav\Common\Data;
|
||||||
use Grav\Common\Page;
|
use Grav\Common\Page\Page;
|
||||||
use Grav\Common\Page\Pages;
|
use Grav\Common\Page\Pages;
|
||||||
use Grav\Common\Page\Collection;
|
use Grav\Common\Page\Collection;
|
||||||
use Grav\Common\Plugin;
|
use Grav\Common\Plugin;
|
||||||
@@ -16,10 +16,10 @@ use Grav\Common\Theme;
|
|||||||
use Grav\Common\User\User;
|
use Grav\Common\User\User;
|
||||||
use Grav\Common\Utils;
|
use Grav\Common\Utils;
|
||||||
use Grav\Common\Backup\ZipBackup;
|
use Grav\Common\Backup\ZipBackup;
|
||||||
use Grav\Common\Markdown\Parsedown;
|
use RocketTheme\Toolbox\Event\Event;
|
||||||
use Grav\Common\Markdown\ParsedownExtra;
|
|
||||||
use RocketTheme\Toolbox\File\File;
|
use RocketTheme\Toolbox\File\File;
|
||||||
use RocketTheme\Toolbox\File\JsonFile;
|
use RocketTheme\Toolbox\File\JsonFile;
|
||||||
|
use Symfony\Component\Yaml\Exception\ParseException;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
|
|
||||||
class AdminController
|
class AdminController
|
||||||
@@ -380,7 +380,7 @@ class AdminController
|
|||||||
protected function taskClearCache()
|
protected function taskClearCache()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('clear cache', ['admin.cache', 'admin.super'])) {
|
if (!$this->authorizeTask('clear cache', ['admin.cache', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get optional cleartype param
|
// get optional cleartype param
|
||||||
@@ -411,7 +411,7 @@ class AdminController
|
|||||||
{
|
{
|
||||||
$param_sep = $this->grav['config']->get('system.param_sep', ':');
|
$param_sep = $this->grav['config']->get('system.param_sep', ':');
|
||||||
if (!$this->authorizeTask('backup', ['admin.maintenance', 'admin.super'])) {
|
if (!$this->authorizeTask('backup', ['admin.maintenance', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$download = $this->grav['uri']->param('download');
|
$download = $this->grav['uri']->param('download');
|
||||||
@@ -562,7 +562,7 @@ class AdminController
|
|||||||
protected function taskListmedia()
|
protected function taskListmedia()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('list media', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('list media', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $this->admin->page(true);
|
$page = $this->admin->page(true);
|
||||||
@@ -583,11 +583,13 @@ class AdminController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles adding a media file to a page
|
* Handles adding a media file to a page
|
||||||
|
*
|
||||||
|
* @return bool True if the action was performed.
|
||||||
*/
|
*/
|
||||||
protected function taskAddmedia()
|
protected function taskAddmedia()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('add media', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('add media', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $this->admin->page(true);
|
$page = $this->admin->page(true);
|
||||||
@@ -597,7 +599,7 @@ class AdminController
|
|||||||
|
|
||||||
if (!isset($_FILES['file']['error']) || is_array($_FILES['file']['error'])) {
|
if (!isset($_FILES['file']['error']) || is_array($_FILES['file']['error'])) {
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.INVALID_PARAMETERS')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.INVALID_PARAMETERS')];
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check $_FILES['file']['error'] value.
|
// Check $_FILES['file']['error'] value.
|
||||||
@@ -606,44 +608,47 @@ class AdminController
|
|||||||
break;
|
break;
|
||||||
case UPLOAD_ERR_NO_FILE:
|
case UPLOAD_ERR_NO_FILE:
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.NO_FILES_SENT')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.NO_FILES_SENT')];
|
||||||
return;
|
return false;
|
||||||
case UPLOAD_ERR_INI_SIZE:
|
case UPLOAD_ERR_INI_SIZE:
|
||||||
case UPLOAD_ERR_FORM_SIZE:
|
case UPLOAD_ERR_FORM_SIZE:
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_FILESIZE_LIMIT')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_FILESIZE_LIMIT')];
|
||||||
return;
|
return false;
|
||||||
default:
|
default:
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.UNKNOWN_ERRORS')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.UNKNOWN_ERRORS')];
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$grav_limit = $config->get('system.media.upload_limit', 0);
|
$grav_limit = $config->get('system.media.upload_limit', 0);
|
||||||
// You should also check filesize here.
|
// You should also check filesize here.
|
||||||
if ($grav_limit > 0 && $_FILES['file']['size'] > $grav_limit) {
|
if ($grav_limit > 0 && $_FILES['file']['size'] > $grav_limit) {
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.EXCEEDED_GRAV_FILESIZE_LIMIT')];
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Check extension
|
// Check extension
|
||||||
$fileParts = pathinfo($_FILES['file']['name']);
|
$fileParts = pathinfo($_FILES['file']['name']);
|
||||||
$fileExt = strtolower($fileParts['extension']);
|
|
||||||
|
|
||||||
// If not a supported type, return
|
$fileExt = '';
|
||||||
if (!$config->get("media.{$fileExt}")) {
|
if (isset($fileParts['extension'])) {
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.UNSUPPORTED_FILE_TYPE') . ': '.$fileExt];
|
$fileExt = strtolower($fileParts['extension']);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If not a supported type, return
|
||||||
|
if (!$fileExt || !$config->get("media.{$fileExt}")) {
|
||||||
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.UNSUPPORTED_FILE_TYPE') . ': '.$fileExt];
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Upload it
|
// Upload it
|
||||||
if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('%s/%s', $page->path(), $_FILES['file']['name']))) {
|
if (!move_uploaded_file($_FILES['file']['tmp_name'], sprintf('%s/%s', $page->path(), $_FILES['file']['name']))) {
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.FAILED_TO_MOVE_UPLOADED_FILE')];
|
$this->admin->json_response = ['status' => 'error', 'message' => $this->admin->translate('PLUGIN_ADMIN.FAILED_TO_MOVE_UPLOADED_FILE')];
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->admin->json_response = ['status' => 'success', 'message' => $this->admin->translate('PLUGIN_ADMIN.FILE_UPLOADED_SUCCESSFULLY')];
|
$this->admin->json_response = ['status' => 'success', 'message' => $this->admin->translate('PLUGIN_ADMIN.FILE_UPLOADED_SUCCESSFULLY')];
|
||||||
|
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -654,7 +659,7 @@ class AdminController
|
|||||||
protected function taskDelmedia()
|
protected function taskDelmedia()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('delete media', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('delete media', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$page = $this->admin->page(true);
|
$page = $this->admin->page(true);
|
||||||
@@ -666,7 +671,7 @@ class AdminController
|
|||||||
|
|
||||||
$filename = !empty($this->post['filename']) ? $this->post['filename'] : null;
|
$filename = !empty($this->post['filename']) ? $this->post['filename'] : null;
|
||||||
if ($filename) {
|
if ($filename) {
|
||||||
$targetPath = $page->path().'/'.$filename;
|
$targetPath = $page->path() . '/' . $filename;
|
||||||
|
|
||||||
if (file_exists($targetPath)) {
|
if (file_exists($targetPath)) {
|
||||||
if (unlink($targetPath)) {
|
if (unlink($targetPath)) {
|
||||||
@@ -677,18 +682,20 @@ class AdminController
|
|||||||
} else {
|
} else {
|
||||||
//Try with responsive images @1x, @2x, @3x
|
//Try with responsive images @1x, @2x, @3x
|
||||||
$ext = pathinfo($targetPath, PATHINFO_EXTENSION);
|
$ext = pathinfo($targetPath, PATHINFO_EXTENSION);
|
||||||
$filename = $page->path() . '/'. basename($targetPath, ".$ext");
|
$fullPathFilename = $page->path() . '/'. basename($targetPath, ".$ext");
|
||||||
$responsiveTargetPath = $filename . '@1x.' . $ext;
|
$responsiveTargetPath = $fullPathFilename . '@1x.' . $ext;
|
||||||
|
|
||||||
$deletedResponsiveImage = false;
|
$deletedResponsiveImage = false;
|
||||||
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
||||||
$deletedResponsiveImage = true;
|
$deletedResponsiveImage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$responsiveTargetPath = $filename . '@2x.' . $ext;
|
$responsiveTargetPath = $fullPathFilename . '@2x.' . $ext;
|
||||||
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
||||||
$deletedResponsiveImage = true;
|
$deletedResponsiveImage = true;
|
||||||
}
|
}
|
||||||
$responsiveTargetPath = $filename . '@3x.' . $ext;
|
|
||||||
|
$responsiveTargetPath = $fullPathFilename . '@3x.' . $ext;
|
||||||
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
if (file_exists($responsiveTargetPath) && unlink($responsiveTargetPath)) {
|
||||||
$deletedResponsiveImage = true;
|
$deletedResponsiveImage = true;
|
||||||
}
|
}
|
||||||
@@ -709,6 +716,8 @@ class AdminController
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Process the page Markdown
|
* Process the page Markdown
|
||||||
|
*
|
||||||
|
* @return bool True if the action was performed.
|
||||||
*/
|
*/
|
||||||
protected function taskProcessMarkdown()
|
protected function taskProcessMarkdown()
|
||||||
{
|
{
|
||||||
@@ -734,11 +743,13 @@ class AdminController
|
|||||||
$html = $page->content();
|
$html = $page->content();
|
||||||
|
|
||||||
$this->admin->json_response = ['status' => 'success', 'message' => $html];
|
$this->admin->json_response = ['status' => 'success', 'message' => $html];
|
||||||
return true;
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
$this->admin->json_response = ['status' => 'error', 'message' => $e->getMessage()];
|
$this->admin->json_response = ['status' => 'error', 'message' => $e->getMessage()];
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -749,7 +760,7 @@ class AdminController
|
|||||||
public function taskEnable()
|
public function taskEnable()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('enable plugin', ['admin.plugins', 'admin.super'])) {
|
if (!$this->authorizeTask('enable plugin', ['admin.plugins', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->view != 'plugins') {
|
if ($this->view != 'plugins') {
|
||||||
@@ -775,7 +786,7 @@ class AdminController
|
|||||||
public function taskDisable()
|
public function taskDisable()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('disable plugin', ['admin.plugins', 'admin.super'])) {
|
if (!$this->authorizeTask('disable plugin', ['admin.plugins', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->view != 'plugins') {
|
if ($this->view != 'plugins') {
|
||||||
@@ -801,7 +812,7 @@ class AdminController
|
|||||||
public function taskActivate()
|
public function taskActivate()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('activate theme', ['admin.themes', 'admin.super'])) {
|
if (!$this->authorizeTask('activate theme', ['admin.themes', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->view != 'themes') {
|
if ($this->view != 'themes') {
|
||||||
@@ -840,7 +851,7 @@ class AdminController
|
|||||||
{
|
{
|
||||||
$type = $this->view === 'plugins' ? 'plugins' : 'themes';
|
$type = $this->view === 'plugins' ? 'plugins' : 'themes';
|
||||||
if (!$this->authorizeTask('install ' . $type, ['admin.' . $type, 'admin.super'])) {
|
if (!$this->authorizeTask('install ' . $type, ['admin.' . $type, 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/gpm.php';
|
require_once __DIR__ . '/gpm.php';
|
||||||
@@ -915,7 +926,7 @@ class AdminController
|
|||||||
|
|
||||||
foreach ($permissions as $type => $p) {
|
foreach ($permissions as $type => $p) {
|
||||||
if (!$this->authorizeTask('update ' . $type , $p)) {
|
if (!$this->authorizeTask('update ' . $type , $p)) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,7 +962,7 @@ class AdminController
|
|||||||
{
|
{
|
||||||
$type = $this->view === 'plugins' ? 'plugins' : 'themes';
|
$type = $this->view === 'plugins' ? 'plugins' : 'themes';
|
||||||
if (!$this->authorizeTask('uninstall ' . $type, ['admin.' . $type, 'admin.super'])) {
|
if (!$this->authorizeTask('uninstall ' . $type, ['admin.' . $type, 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/gpm.php';
|
require_once __DIR__ . '/gpm.php';
|
||||||
@@ -971,6 +982,11 @@ class AdminController
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $file
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
private function cleanFilesData($key, $file)
|
private function cleanFilesData($key, $file)
|
||||||
{
|
{
|
||||||
$config = $this->grav['config'];
|
$config = $this->grav['config'];
|
||||||
@@ -1031,6 +1047,11 @@ class AdminController
|
|||||||
return $cleanFiles[$key];
|
return $cleanFiles[$key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $needle
|
||||||
|
* @param array|string $haystack
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
private function match_in_array($needle, $haystack)
|
private function match_in_array($needle, $haystack)
|
||||||
{
|
{
|
||||||
foreach ((array)$haystack as $item) {
|
foreach ((array)$haystack as $item) {
|
||||||
@@ -1042,6 +1063,10 @@ class AdminController
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param mixed $obj
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
private function processFiles($obj)
|
private function processFiles($obj)
|
||||||
{
|
{
|
||||||
foreach ((array)$_FILES as $key => $file) {
|
foreach ((array)$_FILES as $key => $file) {
|
||||||
@@ -1108,6 +1133,29 @@ class AdminController
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @param string $frontmatter
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function checkValidFrontmatter($frontmatter)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// Try native PECL YAML PHP extension first if available.
|
||||||
|
if (function_exists('yaml_parse')) {
|
||||||
|
$saved = @ini_get('yaml.decode_php');
|
||||||
|
@ini_set('yaml.decode_php', 0);
|
||||||
|
@yaml_parse("---\n" . $frontmatter . "\n...");
|
||||||
|
@ini_set('yaml.decode_php', $saved);
|
||||||
|
} else {
|
||||||
|
Yaml::parse($frontmatter);
|
||||||
|
}
|
||||||
|
} catch (ParseException $e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles form and saves the input data if its valid.
|
* Handles form and saves the input data if its valid.
|
||||||
*
|
*
|
||||||
@@ -1116,21 +1164,27 @@ class AdminController
|
|||||||
public function taskSave()
|
public function taskSave()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('save', $this->dataPermissions())) {
|
if (!$this->authorizeTask('save', $this->dataPermissions())) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->post;
|
$data = $this->post;
|
||||||
|
|
||||||
|
$config = $this->grav['config'];
|
||||||
|
|
||||||
// Special handler for pages data.
|
// Special handler for pages data.
|
||||||
if ($this->view == 'pages') {
|
if ($this->view == 'pages') {
|
||||||
/** @var Page\Pages $pages */
|
/** @var Pages $pages */
|
||||||
$pages = $this->grav['pages'];
|
$pages = $this->grav['pages'];
|
||||||
$config = $this->grav['config'];
|
|
||||||
|
|
||||||
// Find new parent page in order to build the path.
|
// Find new parent page in order to build the path.
|
||||||
$route = !isset($data['route']) ? dirname($this->admin->route) : $data['route'];
|
$route = !isset($data['route']) ? dirname($this->admin->route) : $data['route'];
|
||||||
$obj = $this->admin->page(true);
|
$obj = $this->admin->page(true);
|
||||||
|
|
||||||
|
if (isset($data['frontmatter']) && !$this->checkValidFrontmatter($data['frontmatter'])) {
|
||||||
|
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.INVALID_FRONTMATTER_COULD_NOT_SAVE'), 'error');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//Handle system.home.hide_in_urls
|
//Handle system.home.hide_in_urls
|
||||||
$hide_home_route = $config->get('system.home.hide_in_urls', false);
|
$hide_home_route = $config->get('system.home.hide_in_urls', false);
|
||||||
if ($hide_home_route) {
|
if ($hide_home_route) {
|
||||||
@@ -1187,6 +1241,9 @@ class AdminController
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($obj) {
|
if ($obj) {
|
||||||
|
// Event to manipulate data before saving the object
|
||||||
|
$this->grav->fireEvent('onAdminSave', new Event(['object' => &$obj]));
|
||||||
|
|
||||||
$obj->save(true);
|
$obj->save(true);
|
||||||
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info');
|
$this->admin->setMessage($this->admin->translate('PLUGIN_ADMIN.SUCCESSFULLY_SAVED'), 'info');
|
||||||
}
|
}
|
||||||
@@ -1203,7 +1260,7 @@ class AdminController
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Always redirect if a page route was changed, to refresh it
|
// Always redirect if a page route was changed, to refresh it
|
||||||
if ($obj instanceof Page\Page) {
|
if ($obj instanceof Page) {
|
||||||
if (method_exists($obj, 'unsetRouteSlug')) {
|
if (method_exists($obj, 'unsetRouteSlug')) {
|
||||||
$obj->unsetRouteSlug();
|
$obj->unsetRouteSlug();
|
||||||
}
|
}
|
||||||
@@ -1287,7 +1344,7 @@ class AdminController
|
|||||||
protected function taskCopy()
|
protected function taskCopy()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('copy page', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('copy page', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only applies to pages.
|
// Only applies to pages.
|
||||||
@@ -1296,7 +1353,7 @@ class AdminController
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
/** @var Page\Pages $pages */
|
/** @var Pages $pages */
|
||||||
$pages = $this->grav['pages'];
|
$pages = $this->grav['pages'];
|
||||||
$data = $this->post;
|
$data = $this->post;
|
||||||
|
|
||||||
@@ -1345,7 +1402,7 @@ class AdminController
|
|||||||
protected function taskReorder()
|
protected function taskReorder()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('reorder pages', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('reorder pages', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only applies to pages.
|
// Only applies to pages.
|
||||||
@@ -1366,7 +1423,7 @@ class AdminController
|
|||||||
protected function taskDelete()
|
protected function taskDelete()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('delete page', ['admin.pages', 'admin.super'])) {
|
if (!$this->authorizeTask('delete page', ['admin.pages', 'admin.super'])) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only applies to pages.
|
// Only applies to pages.
|
||||||
@@ -1443,7 +1500,7 @@ class AdminController
|
|||||||
protected function taskSaveas()
|
protected function taskSaveas()
|
||||||
{
|
{
|
||||||
if (!$this->authorizeTask('save', $this->dataPermissions())) {
|
if (!$this->authorizeTask('save', $this->dataPermissions())) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data = $this->post;
|
$data = $this->post;
|
||||||
@@ -1480,7 +1537,7 @@ class AdminController
|
|||||||
$aFile = File::instance($path);
|
$aFile = File::instance($path);
|
||||||
$aFile->save();
|
$aFile->save();
|
||||||
|
|
||||||
$aPage = new Page\Page();
|
$aPage = new Page();
|
||||||
$aPage->init(new \SplFileInfo($path), $language .'.md');
|
$aPage->init(new \SplFileInfo($path), $language .'.md');
|
||||||
$aPage->header($obj->header());
|
$aPage->header($obj->header());
|
||||||
$aPage->rawMarkdown($obj->rawMarkdown());
|
$aPage->rawMarkdown($obj->rawMarkdown());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Grav\Plugin\Admin;
|
namespace Grav\Plugin\Admin;
|
||||||
|
|
||||||
use Grav\Common\GravTrait;
|
use Grav;
|
||||||
use Grav\Common\GPM\GPM as GravGPM;
|
use Grav\Common\GPM\GPM as GravGPM;
|
||||||
use Grav\Common\GPM\Installer;
|
use Grav\Common\GPM\Installer;
|
||||||
use Grav\Common\GPM\Response;
|
use Grav\Common\GPM\Response;
|
||||||
@@ -11,8 +11,6 @@ use Grav\Common\GPM\Common\Package;
|
|||||||
|
|
||||||
class Gpm
|
class Gpm
|
||||||
{
|
{
|
||||||
use GravTrait;
|
|
||||||
|
|
||||||
// Probably should move this to Grav DI container?
|
// Probably should move this to Grav DI container?
|
||||||
protected static $GPM;
|
protected static $GPM;
|
||||||
public static function GPM()
|
public static function GPM()
|
||||||
@@ -36,7 +34,12 @@ class Gpm
|
|||||||
'theme' => false
|
'theme' => false
|
||||||
];
|
];
|
||||||
|
|
||||||
public static function install($packages, $options)
|
/**
|
||||||
|
* @param Package[]|string[]|string $packages
|
||||||
|
* @param array $options
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function install($packages, array $options)
|
||||||
{
|
{
|
||||||
$options = array_merge(self::$options, $options);
|
$options = array_merge(self::$options, $options);
|
||||||
|
|
||||||
@@ -93,13 +96,24 @@ class Gpm
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function update($packages, $options)
|
/**
|
||||||
|
* @param Package[]|string[]|string $packages
|
||||||
|
* @param array $options
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function update($packages, array $options)
|
||||||
{
|
{
|
||||||
$options['overwrite'] = true;
|
$options['overwrite'] = true;
|
||||||
|
|
||||||
return static::install($packages, $options);
|
return static::install($packages, $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function uninstall($packages, $options)
|
/**
|
||||||
|
* @param Package[]|string[]|string $packages
|
||||||
|
* @param array $options
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function uninstall($packages, array $options)
|
||||||
{
|
{
|
||||||
$options = array_merge(self::$options, $options);
|
$options = array_merge(self::$options, $options);
|
||||||
|
|
||||||
@@ -124,7 +138,7 @@ class Gpm
|
|||||||
|
|
||||||
foreach ($packages as $package) {
|
foreach ($packages as $package) {
|
||||||
|
|
||||||
$location = self::getGrav()['locator']->findResource($package->package_type . '://' . $package->slug);
|
$location = Grav::instance()['locator']->findResource($package->package_type . '://' . $package->slug);
|
||||||
|
|
||||||
// Check destination
|
// Check destination
|
||||||
Installer::isValidDestination($location);
|
Installer::isValidDestination($location);
|
||||||
@@ -144,11 +158,15 @@ class Gpm
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function download($package)
|
/**
|
||||||
|
* @param Package $package
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function download(Package $package)
|
||||||
{
|
{
|
||||||
$contents = Response::get($package->zipball_url, []);
|
$contents = Response::get($package->zipball_url, []);
|
||||||
|
|
||||||
$cache_dir = self::getGrav()['locator']->findResource('cache://', true);
|
$cache_dir = Grav::instance()['locator']->findResource('cache://', true);
|
||||||
$cache_dir = $cache_dir . DS . 'tmp/Grav-' . uniqid();
|
$cache_dir = $cache_dir . DS . 'tmp/Grav-' . uniqid();
|
||||||
Folder::mkdir($cache_dir);
|
Folder::mkdir($cache_dir);
|
||||||
|
|
||||||
@@ -159,7 +177,12 @@ class Gpm
|
|||||||
return $cache_dir . DS . $filename . '.zip';
|
return $cache_dir . DS . $filename . '.zip';
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function _downloadSelfupgrade($package, $tmp)
|
/**
|
||||||
|
* @param array $package
|
||||||
|
* @param string $tmp
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private static function _downloadSelfupgrade(array $package, $tmp)
|
||||||
{
|
{
|
||||||
$output = Response::get($package['download'], []);
|
$output = Response::get($package['download'], []);
|
||||||
Folder::mkdir($tmp);
|
Folder::mkdir($tmp);
|
||||||
@@ -167,6 +190,9 @@ class Gpm
|
|||||||
return $tmp . DS . $package['name'];
|
return $tmp . DS . $package['name'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
public static function selfupgrade()
|
public static function selfupgrade()
|
||||||
{
|
{
|
||||||
$upgrader = new Upgrader();
|
$upgrader = new Upgrader();
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ namespace Grav\Plugin;
|
|||||||
|
|
||||||
use Grav\Common\Config\Config;
|
use Grav\Common\Config\Config;
|
||||||
use Grav\Common\Grav;
|
use Grav\Common\Grav;
|
||||||
use Grav\Common\Plugins;
|
|
||||||
use Grav\Common\Themes;
|
|
||||||
use Grav\Common\Page\Page;
|
use Grav\Common\Page\Page;
|
||||||
use Grav\Common\Data;
|
use Grav\Common\Data;
|
||||||
use Grav\Common\GravTrait;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Popularity
|
||||||
|
* @package Grav\Plugin
|
||||||
|
*/
|
||||||
class Popularity
|
class Popularity
|
||||||
{
|
{
|
||||||
use GravTrait;
|
|
||||||
|
|
||||||
/** @var Config */
|
/** @var Config */
|
||||||
protected $config;
|
protected $config;
|
||||||
protected $data_path;
|
protected $data_path;
|
||||||
@@ -36,9 +35,9 @@ class Popularity
|
|||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->config = self::getGrav()['config'];
|
$this->config = Grav::instance()['config'];
|
||||||
|
|
||||||
$this->data_path = self::$grav['locator']->findResource('log://popularity', true, true);
|
$this->data_path = Grav::instance()['locator']->findResource('log://popularity', true, true);
|
||||||
$this->daily_file = $this->data_path.'/'.self::DAILY_FILE;
|
$this->daily_file = $this->data_path.'/'.self::DAILY_FILE;
|
||||||
$this->monthly_file = $this->data_path.'/'.self::MONTHLY_FILE;
|
$this->monthly_file = $this->data_path.'/'.self::MONTHLY_FILE;
|
||||||
$this->totals_file = $this->data_path.'/'.self::TOTALS_FILE;
|
$this->totals_file = $this->data_path.'/'.self::TOTALS_FILE;
|
||||||
@@ -49,13 +48,13 @@ class Popularity
|
|||||||
public function trackHit()
|
public function trackHit()
|
||||||
{
|
{
|
||||||
// Don't track bot or crawler requests
|
// Don't track bot or crawler requests
|
||||||
if (!self::getGrav()['browser']->isHuman()) {
|
if (!Grav::instance()['browser']->isHuman()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var Page $page */
|
/** @var Page $page */
|
||||||
$page = self::getGrav()['page'];
|
$page = Grav::instance()['page'];
|
||||||
$relative_url = str_replace(self::getGrav()['base_url_relative'], '', $page->url());
|
$relative_url = str_replace(Grav::instance()['base_url_relative'], '', $page->url());
|
||||||
|
|
||||||
// Don't track error pages or pages that have no route
|
// Don't track error pages or pages that have no route
|
||||||
if ($page->template() == 'error' || !$page->route()) {
|
if ($page->template() == 'error' || !$page->route()) {
|
||||||
@@ -79,7 +78,7 @@ class Popularity
|
|||||||
$this->updateDaily();
|
$this->updateDaily();
|
||||||
$this->updateMonthly();
|
$this->updateMonthly();
|
||||||
$this->updateTotals($page->route());
|
$this->updateTotals($page->route());
|
||||||
$this->updateVisitors(self::getGrav()['uri']->ip());
|
$this->updateVisitors(Grav::instance()['uri']->ip());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +109,9 @@ class Popularity
|
|||||||
file_put_contents($this->daily_file, json_encode($this->daily_data));
|
file_put_contents($this->daily_file, json_encode($this->daily_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
public function getDailyChartData()
|
public function getDailyChartData()
|
||||||
{
|
{
|
||||||
if (!$this->daily_data) {
|
if (!$this->daily_data) {
|
||||||
@@ -123,13 +125,16 @@ class Popularity
|
|||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
foreach ($chart_data as $date => $count) {
|
foreach ($chart_data as $date => $count) {
|
||||||
$labels[] = self::getGrav()['grav']['admin']->translate(['PLUGIN_ADMIN.' . strtoupper(date('D', strtotime($date)))]);
|
$labels[] = Grav::instance()['grav']['admin']->translate(['PLUGIN_ADMIN.' . strtoupper(date('D', strtotime($date)))]);
|
||||||
$data[] = $count;
|
$data[] = $count;
|
||||||
}
|
}
|
||||||
|
|
||||||
return array('labels' => json_encode($labels), 'data' => json_encode($data));
|
return array('labels' => json_encode($labels), 'data' => json_encode($data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getDailyTotal()
|
public function getDailyTotal()
|
||||||
{
|
{
|
||||||
if (!$this->daily_data) {
|
if (!$this->daily_data) {
|
||||||
@@ -143,6 +148,9 @@ class Popularity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getWeeklyTotal()
|
public function getWeeklyTotal()
|
||||||
{
|
{
|
||||||
if (!$this->daily_data) {
|
if (!$this->daily_data) {
|
||||||
@@ -160,6 +168,9 @@ class Popularity
|
|||||||
return $total;
|
return $total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getMonthlyTotal()
|
public function getMonthlyTotal()
|
||||||
{
|
{
|
||||||
if (!$this->monthly_data) {
|
if (!$this->monthly_data) {
|
||||||
@@ -197,6 +208,9 @@ class Popularity
|
|||||||
file_put_contents($this->monthly_file, json_encode($this->monthly_data));
|
file_put_contents($this->monthly_file, json_encode($this->monthly_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
protected function getMonthyChartData()
|
protected function getMonthyChartData()
|
||||||
{
|
{
|
||||||
if (!$this->monthly_data) {
|
if (!$this->monthly_data) {
|
||||||
@@ -213,6 +227,9 @@ class Popularity
|
|||||||
return array('labels' => $labels, 'data' => $data);
|
return array('labels' => $labels, 'data' => $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
*/
|
||||||
protected function updateTotals($url)
|
protected function updateTotals($url)
|
||||||
{
|
{
|
||||||
if (!$this->totals_data) {
|
if (!$this->totals_data) {
|
||||||
@@ -229,6 +246,9 @@ class Popularity
|
|||||||
file_put_contents($this->totals_file, json_encode($this->totals_data));
|
file_put_contents($this->totals_file, json_encode($this->totals_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $ip
|
||||||
|
*/
|
||||||
protected function updateVisitors($ip)
|
protected function updateVisitors($ip)
|
||||||
{
|
{
|
||||||
if (!$this->visitors_data) {
|
if (!$this->visitors_data) {
|
||||||
@@ -246,6 +266,10 @@ class Popularity
|
|||||||
file_put_contents($this->visitors_file, json_encode($this->visitors_data));
|
file_put_contents($this->visitors_file, json_encode($this->visitors_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
protected function getData($path)
|
protected function getData($path)
|
||||||
{
|
{
|
||||||
if (file_exists($path)) {
|
if (file_exists($path)) {
|
||||||
|
|||||||
@@ -474,4 +474,5 @@ PLUGIN_ADMIN:
|
|||||||
SESSION_HTTPONLY_HELP: "If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed"
|
SESSION_HTTPONLY_HELP: "If true, indicates that cookies should be used only over HTTP, and JavaScript modification is not allowed"
|
||||||
REVERSE_PROXY: "Reverse Proxy"
|
REVERSE_PROXY: "Reverse Proxy"
|
||||||
REVERSE_PROXY_HELP: "Enable this if you are behind a reverse proxy and you are having trouble with URLs containing incorrect ports"
|
REVERSE_PROXY_HELP: "Enable this if you are behind a reverse proxy and you are having trouble with URLs containing incorrect ports"
|
||||||
ADD_FOLDER: "Add Folder"
|
INVALID_FRONTMATTER_COULD_NOT_SAVE: "Invalid frontmatter, could not save"
|
||||||
|
ADD_FOLDER: "Add Folder"
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
title: Config
|
||||||
|
|
||||||
|
access:
|
||||||
|
admin.configuration: true
|
||||||
|
admin.super: true
|
||||||
|
---
|
||||||
|
|||||||
@@ -5,87 +5,3 @@ access:
|
|||||||
admin.login: true
|
admin.login: true
|
||||||
admin.super: true
|
admin.super: true
|
||||||
---
|
---
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
|
||||||
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
|
|
||||||
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
|
|
||||||
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
|
|
||||||
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
|
|||||||
@@ -333,6 +333,19 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Prevent issue caused by a IE / Edge bug sending an empty form with just `route` and `task`
|
||||||
|
var numberOfProperties = 0;
|
||||||
|
for ( var prop in values ) {
|
||||||
|
if (values.hasOwnProperty(prop)) {
|
||||||
|
numberOfProperties++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (numberOfProperties == 2) {
|
||||||
|
if (values.route && values.task) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return form.appendTo('body').submit();
|
return form.appendTo('body').submit();
|
||||||
} else {
|
} else {
|
||||||
return $.ajax({ method: method, url: action, data: values });
|
return $.ajax({ method: method, url: action, data: values });
|
||||||
|
|||||||
@@ -149,7 +149,7 @@
|
|||||||
filename = filename.replace(/@3x|@2x|@1x/, '');
|
filename = filename.replace(/@3x|@2x|@1x/, '');
|
||||||
filename = filename.replace(/\(/g, '%28');
|
filename = filename.replace(/\(/g, '%28');
|
||||||
filename = filename.replace(/\)/g, '%29');
|
filename = filename.replace(/\)/g, '%29');
|
||||||
if (filename.match(/\.(jpg|jpeg|png|gif)$/)) {
|
if (filename.toLowerCase().match(/\.(jpg|jpeg|png|gif)$/)) {
|
||||||
editor.doc.replaceSelection('');
|
editor.doc.replaceSelection('');
|
||||||
} else {
|
} else {
|
||||||
editor.doc.replaceSelection('[' + decodeURI(filename) + '](' + filename + ')');
|
editor.doc.replaceSelection('[' + decodeURI(filename) + '](' + filename + ')');
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ $(function(){
|
|||||||
confirm.open();
|
confirm.open();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('a[href]:not([href^=#])').on('click', function(e){
|
$('a[href]:not([href^="#"])').on('click', function(e){
|
||||||
if (root.currentValues != getState()){
|
if (root.currentValues != getState()){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,8 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% for configuration in admin.configurations %}
|
{% for configuration in admin.configurations %}
|
||||||
{% if configuration != 'system' and configuration != 'site' and admin.data('config/' ~ configuration).blueprints.fields is not empty %}
|
{% set current_blueprints = admin.data('config/' ~ configuration).blueprints.toArray() %}
|
||||||
|
{% if configuration != 'system' and configuration != 'site' and not current_blueprints.form.hidden and current_blueprints.form.fields is not empty %}
|
||||||
<li {% if config_slug == configuration %}class="active"{% endif %}>
|
<li {% if config_slug == configuration %}class="active"{% endif %}>
|
||||||
{% if config_slug == configuration %}<span>{% else %}<a href="{{ base_url_relative }}/config/{{configuration}}">{% endif %}
|
{% if config_slug == configuration %}<span>{% else %}<a href="{{ base_url_relative }}/config/{{configuration}}">{% endif %}
|
||||||
{{ configuration|tu|capitalize }}
|
{{ configuration|tu|capitalize }}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
{% if siblings|length < 200 %}
|
{% if siblings|length < 200 %}
|
||||||
<ul id="ordering" class="{{ field.classes }}">
|
<ul id="ordering" class="{{ field.classes }}">
|
||||||
{% for page in siblings %}
|
{% for page in siblings %}
|
||||||
<li class="{% if page.order == value %}drag-handle{% else %}ignore{% endif %}" data-id="{{ page.slug }}">{{ page.title() }}</li>
|
<li class="{% if page.order == value %}drag-handle{% else %}ignore{% endif %}" data-id="{{ page.slug }}">{{ page.title|e }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|||||||
@@ -57,7 +57,14 @@
|
|||||||
addRemoveLinks: false,
|
addRemoveLinks: false,
|
||||||
dictRemoveFileConfirmation: '[placeholder]',
|
dictRemoveFileConfirmation: '[placeholder]',
|
||||||
acceptedFiles: $('[data-media-types]').data('media-types'),
|
acceptedFiles: $('[data-media-types]').data('media-types'),
|
||||||
previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n <div class=\"dz-filename\"><span data-dz-name></span></div>\n <div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n <div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n <div class=\"dz-success-mark\"><span>✔</span></div>\n <div class=\"dz-error-mark\"><span>✘</span></div>\n <div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>Delete</a>\n<a class=\"dz-insert\" href=\"javascript:undefined;\" data-dz-insert>Insert</a>\n</div>",
|
previewTemplate: "<div class=\"dz-preview dz-file-preview\">\n <div class=\"dz-details\">\n " +
|
||||||
|
"<div class=\"dz-filename\"><span data-dz-name></span></div>\n " +
|
||||||
|
"<div class=\"dz-size\" data-dz-size></div>\n <img data-dz-thumbnail />\n </div>\n " +
|
||||||
|
"<div class=\"dz-progress\"><span class=\"dz-upload\" data-dz-uploadprogress></span></div>\n "+
|
||||||
|
"<div class=\"dz-success-mark\"><span>✔</span></div>\n <div class=\"dz-error-mark\"><span>✘</span></div>\n " +
|
||||||
|
"<div class=\"dz-error-message\"><span data-dz-errormessage></span></div>\n" +
|
||||||
|
"<a class=\"dz-remove\" href=\"javascript:undefined;\" data-dz-remove>Delete</a>\n" +
|
||||||
|
"<a class=\"dz-insert\" href=\"javascript:undefined;\" data-dz-insert>Insert</a>\n</div>",
|
||||||
init: function() {
|
init: function() {
|
||||||
thisDropzone = this;
|
thisDropzone = this;
|
||||||
$.get(URI + '/task{{ config.system.param_sep }}listmedia/admin-nonce{{ config.system.param_sep }}' + GravAdmin.config.admin_nonce, function(data) {
|
$.get(URI + '/task{{ config.system.param_sep }}listmedia/admin-nonce{{ config.system.param_sep }}' + GravAdmin.config.admin_nonce, function(data) {
|
||||||
@@ -73,7 +80,7 @@
|
|||||||
thisDropzone.files.push(mockFile);
|
thisDropzone.files.push(mockFile);
|
||||||
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
|
thisDropzone.options.addedfile.call(thisDropzone, mockFile);
|
||||||
|
|
||||||
if (filename.match(/\.(jpg|jpeg|png|gif)$/)) {
|
if (filename.toLowerCase().match(/\.(jpg|jpeg|png|gif)$/)) {
|
||||||
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, data.url);
|
thisDropzone.options.thumbnail.call(thisDropzone, mockFile, data.url);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,13 +9,22 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if field.fields %}
|
{% if field.fields %}
|
||||||
{% for tab in field.fields %}<input type="radio" name="tab" id="tab{{ loop.index }}" class="tab-head" {{ active == loop.index ? 'checked="checked"' : '' }}/><label for="tab{{ loop.index }}">{% if grav.twig.twig.filters['tu'] is defined %}{{ tab.title|tu }}{% else %}{{ tab.title|t }}{% endif %}</label>{% endfor %}
|
{% for tab in field.fields %}
|
||||||
|
{% if tab.type == 'tab' %}
|
||||||
|
<input type="radio" name="tab" id="tab{{ loop.index }}" class="tab-head" {{ active == loop.index ? 'checked="checked"' : '' }}/>
|
||||||
|
<label for="tab{{ loop.index }}">
|
||||||
|
{% if grav.twig.twig.filters['tu'] is defined %}{{ tab.title|tu }}{% else %}{{ tab.title|t }}{% endif %}
|
||||||
|
</label>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
<div class="tab-body-wrapper">
|
<div class="tab-body-wrapper">
|
||||||
{% for field in field.fields %}
|
{% for field in field.fields %}
|
||||||
{% set value = data.value(field.name) %}
|
{% if field.type == 'tab' %}
|
||||||
<div id="tab-body-{{ loop.index }}" class="tab-body">
|
{% set value = data.value(field.name) %}
|
||||||
{% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
|
<div id="tab-body-{{ loop.index }}" class="tab-body">
|
||||||
</div>
|
{% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
<div class="form-actions secondary-accent">
|
<div class="form-actions secondary-accent">
|
||||||
{% if notAuthorized %}
|
{% if notAuthorized %}
|
||||||
<a class="button secondary" onclick="window.history.back()"><i class="fa fa-reply"></i> {{ 'PLUGIN_ADMIN.BACK'|tu }}</a>
|
<a class="button secondary" onclick="window.history.back()"><i class="fa fa-reply"></i> {{ 'PLUGIN_ADMIN.BACK'|tu }}</a>
|
||||||
|
<button type="submit" class="button primary" name="task" value="logout"><i class="fa fa-sign-in"></i> {{ 'PLUGIN_ADMIN.LOGOUT'|tu }}</button>
|
||||||
{% else %}
|
{% else %}
|
||||||
{% if not authenticated %}
|
{% if not authenticated %}
|
||||||
<a class="button secondary" href="{{ base_url_relative }}/forgot"><i class="fa fa-exclamation-circle"></i> {{ 'PLUGIN_ADMIN.LOGIN_BTN_FORGOT'|tu }}</a>
|
<a class="button secondary" href="{{ base_url_relative }}/forgot"><i class="fa fa-exclamation-circle"></i> {{ 'PLUGIN_ADMIN.LOGIN_BTN_FORGOT'|tu }}</a>
|
||||||
|
|||||||
@@ -89,7 +89,7 @@
|
|||||||
<span {{ p.children(0).count > 0 ? 'data-toggle="children"' : ''}} data-hint="{{ description|trim(' • ') }}" class="hint--bottom">
|
<span {{ p.children(0).count > 0 ? 'data-toggle="children"' : ''}} data-hint="{{ description|trim(' • ') }}" class="hint--bottom">
|
||||||
<i class="page-icon fa fa-fw fa-circle-o {{ p.children(0).count > 0 ? 'children-closed' : ''}} {{ p.modular ? 'modular' : (not p.routable ? 'not-routable' : (not p.visible ? 'not-visible' : (not p.page ? 'folder' : ''))) }}"></i>
|
<i class="page-icon fa fa-fw fa-circle-o {{ p.children(0).count > 0 ? 'children-closed' : ''}} {{ p.modular ? 'modular' : (not p.routable ? 'not-routable' : (not p.visible ? 'not-visible' : (not p.page ? 'folder' : ''))) }}"></i>
|
||||||
</span>
|
</span>
|
||||||
<a href="{{ page_url }}" class="page-edit">{{ p.title }}</a>
|
<a href="{{ page_url }}" class="page-edit">{{ p.title|e }}</a>
|
||||||
|
|
||||||
{% if p.language %}
|
{% if p.language %}
|
||||||
<span class="badge lang {% if p.language == admin_lang %}info{% endif %}">{{p.language}}</span>
|
<span class="badge lang {% if p.language == admin_lang %}info{% endif %}">{{p.language}}</span>
|
||||||
@@ -203,7 +203,7 @@
|
|||||||
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.ADD_PAGE"|tu }}</h1>
|
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.ADD_PAGE"|tu }}</h1>
|
||||||
{% elseif mode == 'edit' %}
|
{% elseif mode == 'edit' %}
|
||||||
<h1><i class="fa fa-fw fa-file-text-o"></i>
|
<h1><i class="fa fa-fw fa-file-text-o"></i>
|
||||||
{{ context.exists ? "PLUGIN_ADMIN.EDIT"|tu ~ " <i>#{context.menu}</i>" : "PLUGIN_ADMIN.CREATE"|tu ~ " <i>#{context.menu}</i>" }}
|
{{ context.exists ? "PLUGIN_ADMIN.EDIT"|tu ~ " <i>#{context.menu|e}</i>" : "PLUGIN_ADMIN.CREATE"|tu ~ " <i>#{context.menu|e}</i>" }}
|
||||||
</h1>
|
</h1>
|
||||||
{% else %}
|
{% else %}
|
||||||
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.MANAGE_PAGES"|tu }}</h1>
|
<h1><i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.MANAGE_PAGES"|tu }}</h1>
|
||||||
|
|||||||
@@ -11,9 +11,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% if header.robots %}
|
{% if header.robots %}
|
||||||
<meta name="robots" content="{{ header.robots }}">
|
<meta name="robots" content="{{ header.robots }}">
|
||||||
|
{% else %}
|
||||||
|
<meta name="robots" content="noindex, nofollow">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<link rel="icon" type="image/png" href="{{ base_url_simple }}{{ theme_url }}/images/favicon.png">
|
<link rel="icon" type="image/png" href="{{ base_url_simple }}/{{ theme_url }}/images/favicon.png">
|
||||||
|
|
||||||
{% block stylesheets %}
|
{% block stylesheets %}
|
||||||
{% do assets.addCss(theme_url~'/css-compiled/nucleus.css') %}
|
{% do assets.addCss(theme_url~'/css-compiled/nucleus.css') %}
|
||||||
|
|||||||
@@ -6,7 +6,11 @@
|
|||||||
<h1>{{ "PLUGIN_ADMIN.LATEST_PAGE_UPDATES"|tu }}</h1>
|
<h1>{{ "PLUGIN_ADMIN.LATEST_PAGE_UPDATES"|tu }}</h1>
|
||||||
<table>
|
<table>
|
||||||
{% for latest in admin.latestPages if admin.latestPages %}
|
{% for latest in admin.latestPages if admin.latestPages %}
|
||||||
<tr><td class="double page-title"><a href="{{ base_url }}/pages/{{ latest.route|trim('/') }}"><i class="fa fa-fw fa-file-o"></i> {{ latest.title }}</a></td><td class="double page-route">{{ latest.route }}</td><td><b class="last-modified">{{ latest.modified|nicetime }}</b></td></tr>
|
<tr>
|
||||||
|
<td class="double page-title">
|
||||||
|
<a href="{{ base_url }}/pages/{{ latest.route|trim('/') }}"><i class="fa fa-fw fa-file-o"></i> {{ latest.title|e }}</a></td><td class="double page-route">{{ latest.route }}</td><td><b class="last-modified">{{ latest.modified|nicetime }}</b>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
|
|
||||||
{#{% if admin.authorize %}#}
|
{#{% if admin.authorize %}#}
|
||||||
<div id="admin-user-details">
|
<div id="admin-user-details">
|
||||||
<a href="{{ base_url_relative }}/users/{{ admin.user.username }}">
|
<a href="{{ base_url_relative }}/users/{{ admin.user.username|e }}">
|
||||||
<img src="//www.gravatar.com/avatar/{{ admin.user.email|md5 }}?s=32" />
|
<img src="//www.gravatar.com/avatar/{{ admin.user.email|md5 }}?s=32" />
|
||||||
|
|
||||||
<div class="admin-user-names">
|
<div class="admin-user-names">
|
||||||
<h4>{{ admin.user.fullname }}</h4>
|
<h4>{{ admin.user.fullname|e }}</h4>
|
||||||
<h5>{{ admin.user.title }}</h5>
|
<h5>{{ admin.user.title|e }}</h5>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<a href="{{ base_url_relative }}/pages">
|
<a href="{{ base_url_relative }}/pages">
|
||||||
<i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.PAGES"|tu }}
|
<i class="fa fa-fw fa-file-text-o"></i> {{ "PLUGIN_ADMIN.PAGES"|tu }}
|
||||||
<span class="badges">
|
<span class="badges">
|
||||||
<span class="badge count">{{ admin.countPages }}</span>
|
<span class="badge count">{{ admin.pagesCount }}</span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,14 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
namespace Grav\Plugin;
|
namespace Grav\Plugin;
|
||||||
|
|
||||||
use \Grav\Common\Grav;
|
use Grav\Common\Grav;
|
||||||
|
use Grav\Common\Language\Language;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
use Symfony\Component\Yaml\Dumper;
|
use Symfony\Component\Yaml\Parser;
|
||||||
|
|
||||||
class AdminTwigExtension extends \Twig_Extension
|
class AdminTwigExtension extends \Twig_Extension
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var Grav
|
||||||
|
*/
|
||||||
protected $grav;
|
protected $grav;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Language $lang
|
||||||
|
*/
|
||||||
|
protected $lang;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->grav = Grav::instance();
|
$this->grav = Grav::instance();
|
||||||
@@ -37,7 +46,7 @@ class AdminTwigExtension extends \Twig_Extension
|
|||||||
|
|
||||||
public function tuFilter()
|
public function tuFilter()
|
||||||
{
|
{
|
||||||
return $this->grav['admin']->translate(func_get_args(), [$this->grav['user']->authenticated ? $this->lang : 'en']);
|
return $this->grav['admin']->translate(func_get_args());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toYamlFilter($value, $inline = true)
|
public function toYamlFilter($value, $inline = true)
|
||||||
|
|||||||
Reference in New Issue
Block a user