322 lines
12 KiB
PHP
Executable File
322 lines
12 KiB
PHP
Executable File
<?php
|
|
namespace Grav\Plugin;
|
|
|
|
use Composer\Autoload\ClassLoader;
|
|
use Grav\Common\Page\Media;
|
|
use Grav\Common\Plugin;
|
|
use Grav\Common\Yaml;
|
|
use RocketTheme\Toolbox\File\File;
|
|
|
|
/**
|
|
* Class AdminAddonMediaMetadataPlugin
|
|
* some of the code is based on the Admin Addon Media Rename by Dávid Szabó
|
|
* see https://github.com/david-szabo97/grav-plugin-admin-addon-media-rename
|
|
* @package Grav\Plugin
|
|
*/
|
|
class AdminAddonMediaMetadataPlugin extends Plugin
|
|
{
|
|
const ROUTE = '/admin-addon-media-metadata';
|
|
const TASK_METADATA = 'AdminAddonMediaMetadataEdit';
|
|
|
|
/**
|
|
* @return array
|
|
*
|
|
* The getSubscribedEvents() gives the core a list of events
|
|
* that the plugin wants to listen to. The key of each
|
|
* array section is the event that the plugin listens to
|
|
* and the value (in the form of an array) contains the
|
|
* callable (or function) as well as the priority. The
|
|
* higher the number the higher the priority.
|
|
*/
|
|
public static function getSubscribedEvents()
|
|
{
|
|
return [
|
|
['autoload', 100000], // TODO: Remove when plugin requires Grav >=1.7
|
|
'onPluginsInitialized' => ['onPluginsInitialized', 0]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Composer autoload.
|
|
* is
|
|
* @return ClassLoader
|
|
*/
|
|
public function autoload(): ClassLoader
|
|
{
|
|
return require __DIR__ . '/vendor/autoload.php';
|
|
}
|
|
|
|
public function getPath()
|
|
{
|
|
return '/' . trim($this->grav['admin']->base, '/') . '/' . trim(self::ROUTE, '/');
|
|
}
|
|
|
|
public function buildBaseUrl()
|
|
{
|
|
return rtrim($this->grav['uri']->rootUrl(true), '/') . '/' . trim($this->getPath(), '/');
|
|
}
|
|
|
|
/**
|
|
* Initialize the plugin
|
|
*/
|
|
public function onPluginsInitialized()
|
|
{
|
|
if (!$this->isAdmin() || !$this->grav['user']->authenticated) {
|
|
return;
|
|
}
|
|
|
|
if ($this->grav['uri']->path() == $this->getPath()) {
|
|
$this->enable([
|
|
'onPagesInitialized' => ['processRenameRequest', 0]
|
|
]);
|
|
return;
|
|
}
|
|
|
|
$this->enable([
|
|
'onTwigTemplatePaths' => ['onTwigTemplatePaths', 0],
|
|
'onPagesInitialized' => ['onTwigExtensions', 0],
|
|
//'onAdminAfterAddMedia' => ['createMetaYaml', 0], // removing the call of this method: see method below
|
|
'onAdminTaskExecute' => ['editMetaDataFile', 0],
|
|
]);
|
|
}
|
|
|
|
public function onTwigTemplatePaths()
|
|
{
|
|
$this->grav['twig']->twig_paths[] = __DIR__ . '/templates';
|
|
}
|
|
|
|
public function onTwigExtensions()
|
|
{
|
|
$page = $this->grav['admin']->page(true);
|
|
if (!$page) {
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* get metadata form field config from plugin admin-addon-media-metadata.yaml file
|
|
* or local override in user/config/plugins/admin-addon-media-metadata.yaml
|
|
* or from page frontmatter
|
|
*/
|
|
//$formFields = $this->config->get('plugins.admin-addon-media-metadata.metadata_form');
|
|
$config = $this->mergeConfig($page, true);
|
|
$formFields = $config->get('metadata_form');
|
|
|
|
/**
|
|
* list all needed data keys from the fields configuration
|
|
*/
|
|
$arrMetaKeys = $this->editableFields($formFields['fields']);
|
|
|
|
$path = $page->path();
|
|
$media = new Media($path);
|
|
$allMedia = $media->all();
|
|
$arrFiles = [];
|
|
$i = 0;
|
|
foreach ($allMedia as $filename => $file) {
|
|
$metadata = $file->meta();
|
|
$arrFiles[$filename] = [
|
|
'filename' => $filename,
|
|
];
|
|
/**
|
|
* for each file: write stored metadata for each editable field into an array
|
|
* this will be output as inline JS variable adminAddonMediaMetadata
|
|
*/
|
|
foreach ($arrMetaKeys as $metaKey => $info) {
|
|
$arrFiles[$filename][$metaKey] = $metadata->$metaKey;
|
|
}
|
|
$i++;
|
|
}
|
|
|
|
$jsArrFormFields = '';
|
|
$i = 0;
|
|
foreach ($arrMetaKeys as $metaKey => $info) {
|
|
$jsArrFormFields .= ($i > 0) ? ",'" . $metaKey . "'" : "'" . $metaKey . "'";
|
|
$i++;
|
|
}
|
|
|
|
$inlineJs = 'var metadataFormFields = [' . $jsArrFormFields . '];';
|
|
$inlineJs .= PHP_EOL . 'var mediaListOnLoad = ' . json_encode($arrFiles) . ';';
|
|
$modal = $this->grav['twig']->twig()->render('metadata-modal.html.twig', $formFields);
|
|
$jsConfig = [
|
|
'PATH' => $this->buildBaseUrl() . '/' . $page->route() . '/task:' . self::TASK_METADATA,
|
|
'MODAL' => $modal
|
|
];
|
|
$inlineJs .= PHP_EOL . 'var adminAddonMediaMetadata = ' . json_encode($jsConfig) . ';';
|
|
$inlineJs .= PHP_EOL . $this->grav['twig']->twig()->render('additionalInlineJS.html.twig');
|
|
$this->grav['assets']->addInlineJs($inlineJs, -1000);
|
|
$this->grav['assets']->addCss('plugin://admin-addon-media-metadata/admin-addon-media-metadata.css', -1000);
|
|
$this->grav['assets']->addJs('plugin://admin-addon-media-metadata/admin-addon-media-metadata.js', -1000);
|
|
}
|
|
|
|
public function editTest()
|
|
{
|
|
$this->outputError('blob');
|
|
}
|
|
|
|
/**
|
|
* writes metadata into the [mediafile].meta.yaml file
|
|
* creates the .meta.yaml file if it does not yet exist
|
|
*/
|
|
public function editMetaDataFile($e)
|
|
{
|
|
$method = $e['method'];
|
|
if ($method === 'task' . self::TASK_METADATA) {
|
|
$fileName = $_POST['filename'];
|
|
|
|
$pageObj = $this->grav['admin']->page();
|
|
$basePath = $pageObj->path() . DS;
|
|
|
|
$filePath = $basePath . $fileName;
|
|
|
|
/**
|
|
* temporarily removing the condition that checks for the media file to exist
|
|
* as in Admin plugin 1.10 a media file will be uploaded to a tmp folder first
|
|
* and moved to the page folder on saving the page
|
|
*
|
|
* there needs to be a better solution for this
|
|
*
|
|
* also: take care of system.yaml → media.auto_metadata_exif
|
|
* if set to TRUE, a meta.yaml with EXIF data will be written, but only if the meta.yaml does not yet exist
|
|
* in Admin 1.10 you need to save a page in order to have the meta.yaml file with EXIF data created
|
|
* in Admin 1.9 this is not a problem since this plugin now (>=1.1.0) writes metadata only when needed
|
|
*/
|
|
// if (!file_exists($filePath)) {
|
|
// $this->outputError($this->grav['language']->translate(['PLUGIN_ADMIN_ADDON_MEDIA_METADATA.ERRORS.MEDIA_FILE_NOT_FOUND', $filePath]));
|
|
// } else {
|
|
$metaDataFilePath = $filePath . '.meta.yaml';
|
|
|
|
/**
|
|
* get the list of form data from the fields configuration
|
|
*/
|
|
$arrMetaKeys = $this->editableFields();
|
|
|
|
if (file_exists($metaDataFilePath)) {
|
|
/**
|
|
* get array of all current metadata for the file
|
|
* this is to avoid overwriting data that has been added to the meta.yaml file in the file browser
|
|
*/
|
|
$storedMetaData = Yaml::parse(file_get_contents($metaDataFilePath));
|
|
|
|
/**
|
|
* overwrite the currently stored data for each field in the form
|
|
*/
|
|
foreach ($arrMetaKeys as $metaKey => $info) {
|
|
if (isset($_POST[$metaKey])) {
|
|
$storedMetaData[$metaKey] = $_POST[$metaKey];
|
|
}
|
|
}
|
|
|
|
} else {
|
|
/**
|
|
* create metaData in case the meta data file does not yet exist
|
|
*/
|
|
$storedMetaData = [];
|
|
foreach ($arrMetaKeys as $metaKey => $info) {
|
|
if (isset($_POST[$metaKey])) {
|
|
$storedMetaData[$metaKey] = $_POST[$metaKey];
|
|
} else {
|
|
$storedMetaData[$metaKey] = '';
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get an instance of the meta file and write the data to it
|
|
* @see \Grav\Common\Page\Media
|
|
*/
|
|
$metaDataFile = File::instance($metaDataFilePath);
|
|
$metaDataFile->save(Yaml::dump($storedMetaData));
|
|
|
|
//$this->outputError($newYamlText);
|
|
// }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* this method will not be called in Admin Plugin v1.10 (up until rc.11 anyway)
|
|
* additionally, writing the YAML file on upload will meddle with the system functionality
|
|
* that writes exif data
|
|
* in Admin Plugin v1.9 this functionality writes the meta.yaml file
|
|
* on upload, this plugin will then just add the other metadata
|
|
* when writing the meta.yaml file upon upload the system functionality will be overwritten
|
|
* in Admin Plugin v1.10 you need to save the page before using this plugin on a file
|
|
* if you want the exif data to be stored
|
|
*/
|
|
/**
|
|
* creates an image.meta.yaml file
|
|
* this file will be deleted by the core when deleting an image
|
|
* will be called after a media file has been added (see onPluginsInitialized())
|
|
*/
|
|
// public function createMetaYaml()
|
|
// {
|
|
// $fileName = $_FILES['file']['name'];
|
|
//
|
|
// $pageObj = $this->grav['admin']->page();
|
|
// $basePath = $pageObj->path() . DS;
|
|
//
|
|
// $filePath = $basePath . $fileName;
|
|
// if (!file_exists($filePath)) {
|
|
// $this->outputError($this->grav['language']->translate(['PLUGIN_ADMIN_ADDON_MEDIA_METADATA.ERRORS.MEDIA_FILE_NOT_FOUND', $filePath]));
|
|
// } else {
|
|
// // TODO: do that only for image files?
|
|
// $metaDataFileName = $fileName . '.meta.yaml';
|
|
// $metaDataFilePath = $basePath . $metaDataFileName;
|
|
// if (!file_exists($metaDataFilePath)) {
|
|
// /**
|
|
// * get the list of form data from the fields configuration
|
|
// */
|
|
// $arrMetaKeys = $this->editableFields();
|
|
//
|
|
// $newMetaData = [];
|
|
// foreach ($arrMetaKeys as $metaKey => $info) {
|
|
// $newMetaData[$metaKey] = '';
|
|
// }
|
|
//
|
|
// /**
|
|
// * Get an instance of the meta file and write the data to it
|
|
// * @see \Grav\Common\Page\Media
|
|
// */
|
|
// $metaDataFile = File::instance($metaDataFilePath);
|
|
// $metaDataFile->save(Yaml::dump($newMetaData));
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
/**
|
|
* return all editable fields from form configuration
|
|
*/
|
|
private function editableFields($fieldsConf = null)
|
|
{
|
|
if ($fieldsConf === null) {
|
|
$page = $this->grav['admin']->page(true);
|
|
if (!$page) {
|
|
return;
|
|
}
|
|
/**
|
|
* get metadata form field config from plugin admin-addon-media-metadata.yaml file
|
|
* or local override in user/config/plugins/admin-addon-media-metadata.yaml
|
|
* or from page frontmatter
|
|
*/
|
|
//$formFields = $this->config->get('plugins.admin-addon-media-metadata.metadata_form');
|
|
$config = $this->mergeConfig($page, true);
|
|
$formFields = $config->get('metadata_form');
|
|
$fieldsConf = $formFields['fields'];
|
|
}
|
|
$arrMetaKeys = [];
|
|
foreach ($fieldsConf as $singleFieldConf) {
|
|
if (isset($singleFieldConf['name'], $singleFieldConf['type']) && $singleFieldConf['name'] !== 'filename') {
|
|
$arrMetaKeys[$singleFieldConf['name']] = [
|
|
'name' => $singleFieldConf['name'],
|
|
'type' => $singleFieldConf['type']
|
|
];
|
|
}
|
|
}
|
|
return $arrMetaKeys;
|
|
}
|
|
|
|
public function outputError($msg)
|
|
{
|
|
header('HTTP/1.1 400 Bad Request');
|
|
die(json_encode(['error' => ['msg' => $msg]]));
|
|
}
|
|
}
|