Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 142 additions & 1 deletion core/src/Revolution/Processors/System/Log/GetList.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@
namespace MODX\Revolution\Processors\System\Log;

use MODX\Revolution\Formatter\modManagerDateFormatter;
use MODX\Revolution\modAccessPolicy;
use MODX\Revolution\modAccessPolicyTemplate;
use MODX\Revolution\modCategory;
use MODX\Revolution\modChunk;
use MODX\Revolution\modContext;
use MODX\Revolution\modContextSetting;
use MODX\Revolution\modContentType;
use MODX\Revolution\modDashboard;
use MODX\Revolution\modDashboardWidget;
use MODX\Revolution\modDocument;
use MODX\Revolution\modManagerLog;
use MODX\Revolution\modMenu;
use MODX\Revolution\modNamespace;
use MODX\Revolution\modPlugin;
use MODX\Revolution\modResource;
use MODX\Revolution\modResourceGroup;
use MODX\Revolution\modSnippet;
use MODX\Revolution\modStaticResource;
use MODX\Revolution\modSymLink;
use MODX\Revolution\modSystemSetting;
Expand All @@ -27,6 +37,8 @@
use MODX\Revolution\modUserSetting;
use MODX\Revolution\modWebLink;
use MODX\Revolution\Processors\Processor;
use MODX\Revolution\Sources\modMediaSource;
use MODX\Revolution\Transport\modTransportPackage;
use xPDO\Om\xPDOObject;

/**
Expand Down Expand Up @@ -194,9 +206,10 @@ public function prepareLog(modManagerLog $log)
$path = $this->modx->getOption("{$ns}.core_path", null, $nsCorePath) . 'model/';
$this->modx->addPackage($ns, $path);
}
$obj = null;
if (!empty($logArray['classKey']) && !empty($logArray['item'])) {
$logArray['name'] = $logArray['classKey'] . ' (' . $logArray['item'] . ')';
/** @var xPDOObject $obj */
/** @var xPDOObject|null $obj */
$obj = $this->modx->getObject($logArray['classKey'], $logArray['item']);
if ($obj && ($obj->get($obj->getPK()) === $logArray['item'])) {
$nameField = $this->getNameField($logArray['classKey']);
Expand All @@ -209,6 +222,14 @@ public function prepareLog(modManagerLog $log)
} else {
$logArray['name'] = $log->get('item');
}

$managerUrl = $this->getManagerUrl(
$logArray['classKey'] ?? '',
$logArray['item'] ?? '',
$obj
);
$logArray['managerUrl'] = $managerUrl;

$customFormat = $this->getProperty('dateFormat');
$logArray['occurred'] = !empty($customFormat)
? $this->formatter->format($logArray['occurred'], $customFormat)
Expand All @@ -218,6 +239,126 @@ public function prepareLog(modManagerLog $log)
return $logArray;
}

/**
* Build manager URL for a log entry so the object can be opened in the manager.
*
* @param string $classKey Class key of the logged object
* @param string $item Primary key value stored in the log
* @param xPDOObject|null $obj Loaded object when available (used for context key, menu text, etc.)
* @return string|null Relative URL (e.g. ?a=resource/update&id=1) or null when no link is supported
*/
protected function getManagerUrl(string $classKey, string $item, ?xPDOObject $obj = null): ?string
{
if (empty($classKey) || $item === '' || $item === 'unknown') {
return null;
}

$action = null;
$paramKey = 'id';
$paramValue = $item;

switch ($classKey) {
case modResource::class:
case modWebLink::class:
case modSymLink::class:
case modStaticResource::class:
case modDocument::class:
$action = 'resource/update';
break;
case modContext::class:
$action = 'context/update';
$paramKey = 'key';
$paramValue = ($obj !== null) ? (string) $obj->get('key') : $item;
if ($paramValue === '') {
return null;
}
break;
case modTemplate::class:
$action = 'element/template/update';
break;
case modChunk::class:
$action = 'element/chunk/update';
break;
case modSnippet::class:
$action = 'element/snippet/update';
break;
case modPlugin::class:
$action = 'element/plugin/update';
break;
case modCategory::class:
$action = 'element/category/update';
break;
case modUser::class:
$action = 'security/user/update';
break;
case modMenu::class:
$action = 'element/menu/update';
$paramKey = 'text';
$paramValue = ($obj !== null) ? (string) $obj->get('text') : $item;
if ($paramValue === '') {
return null;
}
break;
case modSystemSetting::class:
return null;
case modContextSetting::class:
$action = 'context/update';
$paramKey = 'key';
$paramValue = ($obj !== null) ? (string) $obj->get('context_key') : $item;
if ($paramValue === '') {
return null;
}
break;
case modUserSetting::class:
$action = 'security/user/update';
$paramValue = ($obj !== null) ? (string) $obj->get('user') : $item;
break;
case modAccessPolicy::class:
$action = 'security/access/policy/update';
break;
case modAccessPolicyTemplate::class:
$action = 'security/access/policy/template/update';
break;
case modResourceGroup::class:
$action = 'security/resourcegroup/update';
break;
case modMediaSource::class:
$action = 'source/update';
break;
case modNamespace::class:
$action = 'workspace/namespace/update';
$paramKey = 'name';
$paramValue = ($obj !== null) ? (string) $obj->get('name') : $item;
if ($paramValue === '') {
return null;
}
break;
case modDashboardWidget::class:
$action = 'system/dashboard/widget/update';
break;
case modDashboard::class:
$action = 'system/dashboard/update';
break;
case modTransportPackage::class:
$action = 'workspace/packages/view';
$paramKey = 'signature';
$paramValue = ($obj !== null) ? (string) $obj->get('signature') : $item;
if ($paramValue === '') {
return null;
}
break;
case modContentType::class:
$action = 'system/contenttype/update';
break;
default:
return null;
}

$params = [$paramKey => $paramValue];

return '?a=' . $action . '&' . http_build_query($params, '', '&', PHP_QUERY_RFC3986);
}

/**
* Get the name field of the class
* @param string $classKey
Expand Down
23 changes: 21 additions & 2 deletions manager/assets/modext/widgets/system/modx.grid.manager.log.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ MODx.grid.ManagerLog = function(config) {
,baseParams: {
action: 'System/Log/GetList'
}
,fields: ['id','user','username','occurred','action','classKey','item','name','menu']
,fields: ['id','user','username','occurred','action','classKey','item','name','managerUrl','menu']
,showActionsColumn: false
,autosave: false
,paging: true
Expand All @@ -193,13 +193,32 @@ MODx.grid.ManagerLog = function(config) {
header: _('object')
,dataIndex: 'name'
,width: 300
,renderer: Ext.util.Format.htmlEncode
,renderer: function(value, metaData, record) {
return this.renderObjectCell(value, metaData, record);
}
,scope: this
}]
,tbar: this.getTbar()
});
MODx.grid.ManagerLog.superclass.constructor.call(this,config);
};
Ext.extend(MODx.grid.ManagerLog,MODx.grid.Grid, {
renderObjectCell: function(value, metaData, record) {
var managerUrl = record.data.managerUrl;
var item = record.data.item;
if (!managerUrl || item === undefined || item === null) {
return Ext.util.Format.htmlEncode(value);
}
var baseUrl = MODx.config.manager_url || '';
var href = baseUrl + managerUrl;
var idSuffix = ' (' + item + ')';
if (value && String(value).slice(-idSuffix.length) === idSuffix) {
var nameWithoutId = value.slice(0, value.length - idSuffix.length);
return Ext.util.Format.htmlEncode(nameWithoutId) + ' ' + this.renderLink(idSuffix, { href: href, target: '_blank' });
}
return this.renderLink(value, { href: href, target: '_blank' });
},

getTbar: function() {
var tbar = [{
xtype: 'button'
Expand Down