use namespace (and nearly full rewrite)
This commit is contained in:
parent
81d9f1e944
commit
02edbcb877
@ -17,6 +17,5 @@ if (!defined('DC_RC_PATH')) {
|
|||||||
class initActivityReport
|
class initActivityReport
|
||||||
{
|
{
|
||||||
public const ACTIVITY_TABLE_NAME = 'activity';
|
public const ACTIVITY_TABLE_NAME = 'activity';
|
||||||
public const SETTING_TABLE_NAME = 'activity_setting';
|
|
||||||
public const CACHE_DIR_NAME = 'activityreport';
|
public const CACHE_DIR_NAME = 'activityreport';
|
||||||
}
|
}
|
||||||
|
2
icon.svg
Normal file
2
icon.svg
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<svg fill="#B2B2B2" width="64px" height="64px" viewBox="0 0 24 24" id="frequency" data-name="Flat Color" xmlns="http://www.w3.org/2000/svg" class="icon flat-color"><path id="primary" d="M9,17a1,1,0,0,1-.89-.55L6.38,13H3a1,1,0,0,1,0-2H7a1,1,0,0,1,.89.55L9,13.76l3.11-6.21A1.05,1.05,0,0,1,13,7a1,1,0,0,1,.89.61l2.27,5.3,1-1.46A1,1,0,0,1,18,11h3a1,1,0,0,1,0,2H18.54l-1.71,2.55a1,1,0,0,1-.92.45,1,1,0,0,1-.83-.61l-2.15-5-3,6.07A1,1,0,0,1,9,17Z"></path></svg>
|
After Width: | Height: | Size: 493 B |
10
js/backend.js
Normal file
10
js/backend.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/*global $, dotclear */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Object.assign(dotclear.msg, dotclear.getData('activityReport'));
|
||||||
|
|
||||||
|
$(() => {
|
||||||
|
$('#form-logs').on('submit', function () {
|
||||||
|
return window.confirm(dotclear.msg.confirm_delete);
|
||||||
|
});
|
||||||
|
});
|
91
js/main.js
91
js/main.js
@ -1,91 +0,0 @@
|
|||||||
/* -- BEGIN LICENSE BLOCK ----------------------------------
|
|
||||||
* This file is part of activityReport, a plugin for Dotclear 2.
|
|
||||||
*
|
|
||||||
* Copyright (c) 2009-2010 JC Denis and contributors
|
|
||||||
* jcdenis@gdwd.com
|
|
||||||
*
|
|
||||||
* Licensed under the GPL version 2.0 license.
|
|
||||||
* A copy of this license is available in LICENSE file or at
|
|
||||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
||||||
* -- END LICENSE BLOCK ------------------------------------*/
|
|
||||||
|
|
||||||
$(function(){
|
|
||||||
/* tools */
|
|
||||||
dotclear.jcTools = new jcToolsBox();
|
|
||||||
|
|
||||||
/* setting blog */
|
|
||||||
var bForm=$('#setting-blog-form');
|
|
||||||
if ($(bForm).attr('id')!=undefined){
|
|
||||||
dotclear.jcTools.formFieldsetToMenu(bForm);
|
|
||||||
$(bForm).submit(function(){dotclear.jcTools.waitMessage();return true;});
|
|
||||||
}
|
|
||||||
/* setting global */
|
|
||||||
var gForm=$('#setting-super-form');
|
|
||||||
if ($(gForm).attr('id')!=undefined){
|
|
||||||
dotclear.jcTools.formFieldsetToMenu(gForm);
|
|
||||||
$(gForm).submit(function(){dotclear.jcTools.waitMessage();return true;});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
function jcToolsBox(){}
|
|
||||||
|
|
||||||
jcToolsBox.prototype={
|
|
||||||
text_wait:'Please wait',
|
|
||||||
section:'',
|
|
||||||
|
|
||||||
formFieldsetToMenu:function(form){
|
|
||||||
var This=this;
|
|
||||||
var section=$(form).children('fieldset[id='+This.section+']').attr('id');
|
|
||||||
var hidden_section=$(form).children('input[name=section]').attr('value');
|
|
||||||
var formMenu=$(form).children('p.formMenu').get(0);
|
|
||||||
if (formMenu==undefined) {
|
|
||||||
$(form).prepend($('<p></p>').addClass('formMenu'));
|
|
||||||
}
|
|
||||||
$(form).children('fieldset').each(function(){
|
|
||||||
var Fieldset=this;
|
|
||||||
$(Fieldset).hide();
|
|
||||||
var title=$(Fieldset).children('legend').text();
|
|
||||||
var menu=$('<a></a>').text(title).addClass('button').attr('tabindex','2').click(
|
|
||||||
function(){
|
|
||||||
var fieldset_visible=$(form).children('fieldset:visible');
|
|
||||||
if (fieldset_visible==undefined){
|
|
||||||
$(Fieldset).slideDown('slow');$(form).children('input[type=submit]').show();
|
|
||||||
}else{
|
|
||||||
$(fieldset_visible).fadeOut('fast',function(){$(Fieldset).fadeIn('fast');$(form).children('input[type=submit]').show();})
|
|
||||||
}
|
|
||||||
if (hidden_section==undefined){
|
|
||||||
$(form).children('input[name=section]').remove();
|
|
||||||
$(form).append($('<input type="hidden" />').attr('name','section').attr('value',$(Fieldset).attr('id')));
|
|
||||||
}
|
|
||||||
$('.message').fadeOut('slow',function(){$(this).slideUp('slow',function(){$(this).remove();})});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
$(form).children('.formMenu').append(menu).append(' ');
|
|
||||||
});
|
|
||||||
if (section!=undefined){
|
|
||||||
$(form).children('fieldset[id='+section+']').show();
|
|
||||||
}else{
|
|
||||||
$(form).children('fieldset:first').show();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
waitMessage:function(){
|
|
||||||
var This=this;
|
|
||||||
var content=$('div[id=content]');
|
|
||||||
if (content!=undefined){
|
|
||||||
$(content).hide();
|
|
||||||
}else{
|
|
||||||
$('input').hide();$('select').hide();
|
|
||||||
content=$('body');
|
|
||||||
}
|
|
||||||
var text=$('<p></p>').addClass('message').text(This.text_wait);
|
|
||||||
This.blinkItem(text);
|
|
||||||
var box=$('<div></div>').attr('style','margin: 60px auto auto;width:200px;').append(text);
|
|
||||||
$(content).before($(box));
|
|
||||||
},
|
|
||||||
|
|
||||||
blinkItem:function(item){
|
|
||||||
var This=this;
|
|
||||||
$(item).fadeOut('slow',function(){$(this).fadeIn('slow',function(){This.blinkItem(this);})});
|
|
||||||
}
|
|
||||||
}
|
|
108
locales/fr/main.lang.php
Normal file
108
locales/fr/main.lang.php
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @package Dotclear
|
||||||
|
*
|
||||||
|
* @copyright Olivier Meunier & Association Dotclear
|
||||||
|
* @copyright GPL-2.0-only
|
||||||
|
*/
|
||||||
|
#
|
||||||
|
# DOT NOT MODIFY THIS FILE !
|
||||||
|
#
|
||||||
|
|
||||||
|
use Dotclear\Helper\L10n;
|
||||||
|
|
||||||
|
L10n::$locales['ActivityReport messages'] = 'Messages de l\'extension';
|
||||||
|
L10n::$locales['Actions on blog'] = 'Actions sur le blog';
|
||||||
|
L10n::$locales['Actions on posts'] = 'Actions sur les billets';
|
||||||
|
L10n::$locales['Actions on comments'] = 'Actions sur les commentaires';
|
||||||
|
L10n::$locales['Actions on categories'] = 'Actions sur les catégories';
|
||||||
|
L10n::$locales['Actions on users'] = 'Actions sur les utilisateurs';
|
||||||
|
L10n::$locales['Special messages'] = 'Messages spéciaux';
|
||||||
|
L10n::$locales['%s'] = '%s';
|
||||||
|
L10n::$locales['updating blog'] = 'Mise à jour du blog';
|
||||||
|
L10n::$locales['Blog was updated by "%s"'] = 'Blog mis à jour par "%s"';
|
||||||
|
L10n::$locales['404 error'] = 'Erreur 404';
|
||||||
|
L10n::$locales['New 404 error page at "%s"'] = 'Nouvelle erreur 404 à l\'adresse "%s"';
|
||||||
|
L10n::$locales['post creation'] = 'Création de billet';
|
||||||
|
L10n::$locales['A new post called "%s" was created by "%s" at %s'] = 'Un nouveau billet nommé "%s" a été créé par "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['updating post'] = 'Mise à jour de billet';
|
||||||
|
L10n::$locales['Post called "%s" has been updated by "%s" at %s'] = 'Le billet nommé "%s" a été mis à jour par "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['post deletion'] = 'Suppression de billet';
|
||||||
|
L10n::$locales['Post called "%s" has been deleted by "%s"'] = 'Le billet nommé "%s" a été supprimé par "%s"';
|
||||||
|
L10n::$locales['Post protection'] = 'Protection des billets';
|
||||||
|
L10n::$locales['An attempt failed on a passworded post with password "%s" at "%s"'] = 'Une tentative a échoué sur un billet protégé par mot de passe avec l\'essai "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['comment creation'] = 'Création de commentaire';
|
||||||
|
L10n::$locales['A new comment was created by "%s" on post "%s" at %s'] = 'Un nouveau commentaire a été créé par "%s" sur le billet "%s"';
|
||||||
|
L10n::$locales['updating comment'] = 'Mise à jour de commentaire';
|
||||||
|
L10n::$locales['Comment has been updated by "%s" at %s'] = 'Un commentaire a été mise à jour par "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['trackback creation'] = 'Création de trackback';
|
||||||
|
L10n::$locales['A new trackback to "%" at "%s" was created on post "%s" at %s'] = 'Un nouveau rétrolien vers "%s" a été créé sur le billet "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['category creation'] = 'Création de catégorie';
|
||||||
|
L10n::$locales['A new category called "%s" was created by "%s" at %s'] = 'Un nouvelle catégorie nommée "%s" a été créé par "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['updating category'] = 'Mise à jour de catégorie';
|
||||||
|
L10n::$locales['Category called "%s" has been updated by "%s" at %s'] = 'La catégorie nommée "%s" a été mise à jour par "%s" à l\'adresse "%s"';
|
||||||
|
L10n::$locales['user creation'] = 'Création d\'utilisateur';
|
||||||
|
L10n::$locales['A new user named "%s" was created by "%s"'] = 'Un nouvel utilisateur a été ajouté par "%s"';
|
||||||
|
L10n::$locales['updating user'] = 'Mise à jour d\'utilisateur';
|
||||||
|
L10n::$locales['User named "%s" has been updated by "%s"'] = 'L\'utilisateur "%s" a été mis à jour par "%s"';
|
||||||
|
L10n::$locales['user deletion'] = 'Suppression d\'utilisateur';
|
||||||
|
L10n::$locales['User named "%s" has been deleted by "%"'] = 'L\'utilisateur nommé "%s" a été supprimé par "%s"';
|
||||||
|
L10n::$locales['HTML'] = 'HTML';
|
||||||
|
L10n::$locales['Activity report'] = 'Rapport d\'activité';
|
||||||
|
L10n::$locales['An error occured when parsing report.'] = 'Une erreur est survenue lors de la compilation du rapport.';
|
||||||
|
L10n::$locales['You received a message from your blog\'s activity report module.'] = 'Vous recevez un message du module de rapport d\'activité de votre blog.';
|
||||||
|
L10n::$locales['Period from %s to %s'] = 'Période du %s au %s';
|
||||||
|
L10n::$locales['Activity report deletes some old logs.'] = 'L\'extension a automatiquement effacé des anciennes activités.';
|
||||||
|
L10n::$locales['Blog "%s" activity report'] = 'Rapport d\'activité du blog "%s"';
|
||||||
|
L10n::$locales['View all logs'] = 'Voir tous les logs';
|
||||||
|
L10n::$locales['Number of activities to show on dashboard:'] = 'Nombre d\'activités à afficher sur le tableau de bord :';
|
||||||
|
L10n::$locales['Do not show activity report'] = 'Ne pas afficher le rapport d\'activité';
|
||||||
|
L10n::$locales['Group'] = 'Groupe';
|
||||||
|
L10n::$locales['logs per page'] = 'enregistrements par page';
|
||||||
|
L10n::$locales['every hour'] = 'toutes les heures';
|
||||||
|
L10n::$locales['every 2 hours'] = 'toutes les 2 heures';
|
||||||
|
L10n::$locales['2 times by day'] = '2 fois par jour';
|
||||||
|
L10n::$locales['every day'] = 'tous les jours';
|
||||||
|
L10n::$locales['every 2 days'] = 'tous les 2 jours';
|
||||||
|
L10n::$locales['every week'] = 'toutes les semaines';
|
||||||
|
L10n::$locales['every 2 weeks'] = 'toutes les 2 semaines';
|
||||||
|
L10n::$locales['every 4 weeks'] = 'toutes les 4 semaines';
|
||||||
|
L10n::$locales['Report successfully sent.'] = 'Rapport envoyé avec succès.';
|
||||||
|
L10n::$locales['Logs successfully deleted.'] = 'Logs effacés avec succès.';
|
||||||
|
L10n::$locales['never'] = 'jamais';
|
||||||
|
L10n::$locales['on new activity'] = 'lors d\'une nouvelle activité';
|
||||||
|
L10n::$locales['This server has no mail function, activityReport does not send email report.'] = 'Ce server n\'a pas de fonction d\'envoie de mail, le rapport ne sera pas envoyer.';
|
||||||
|
L10n::$locales['Mail report'] = 'Rapport par email';
|
||||||
|
L10n::$locales['Send report:'] = 'Rapport envoyé :';
|
||||||
|
L10n::$locales['Recipients:'] = 'Destinataires :';
|
||||||
|
L10n::$locales['Separate multiple email addresses with a semicolon ";"'] = 'Séparer les adresses email par un point-virgule ";"';
|
||||||
|
L10n::$locales['Leave it empty to disable mail report.'] = 'Laisser vide pour désactiver le rapport par email.';
|
||||||
|
L10n::$locales['Use Dotclear date formaters. ex: %B %d at %H:%M'] = 'Utiliser le formatage des dates de Dotclear. ex: %d %B à %H:%M';
|
||||||
|
L10n::$locales['Report format:'] = 'Format du rapport :';
|
||||||
|
L10n::$locales['Last report by email:'] = 'Dernier rapport par email :';
|
||||||
|
L10n::$locales['Next report by email:'] = 'Prochain rapport par email :';
|
||||||
|
L10n::$locales['Feeds'] = 'Flux';
|
||||||
|
L10n::$locales['Enable activity feed'] = 'Activer le flux d\'activités';
|
||||||
|
L10n::$locales['RSS feed'] = 'Flux RSS';
|
||||||
|
L10n::$locales['Rss2 activities feed'] = 'Flux RSS2 d\'activités';
|
||||||
|
L10n::$locales['Atom feed'] = 'Flux Atom';
|
||||||
|
L10n::$locales['Atom activities feed'] = 'Flux Atom d\'activités';
|
||||||
|
L10n::$locales['Activities'] = 'Activités';
|
||||||
|
L10n::$locales['Select actions by activity type to add to report'] = 'Sélectionner les actions par type d\'activité à ajouter au rapport';
|
||||||
|
L10n::$locales['Automatic cleaning of old logs:'] = 'Nettoyage automatique des anciennes activités:';
|
||||||
|
L10n::$locales['Send report now'] = 'Envoyer un rapport maintenant';
|
||||||
|
L10n::$locales['Delete all logs now'] = 'Effacer tous les logs maintenant';
|
||||||
|
L10n::$locales['Plain text'] = 'Texte brut';
|
||||||
|
L10n::$locales['Logs successfully deleted'] = 'Enregistrements effacés avec succès';
|
||||||
|
L10n::$locales['Are you sure you want to delete logs?'] = 'Êtes-vous sure de vouloir effacer les enregistrements ?';
|
||||||
|
L10n::$locales['Delete all aticivity logs'] = 'Effacer tous les enregistrements d\'activités';
|
||||||
|
L10n::$locales['Delete all allready reported logs'] = 'Effacer les enregistrements d\'activités déjà envoyé par email';
|
||||||
|
L10n::$locales['No log matches the filter'] = 'Aucun enregistrement ne correspond au filtre';
|
||||||
|
L10n::$locales['No log'] = 'Pas d\'enregistrement';
|
||||||
|
L10n::$locales['List of %s logs matching the filter.'] = 'Liste des %s logs correspondants au filtre.';
|
||||||
|
L10n::$locales['List of %s logs.'] = 'Listes des %s enregistrements';
|
||||||
|
L10n::$locales['Message'] = 'Message';
|
||||||
|
L10n::$locales['undefined'] = 'inconnu';
|
||||||
|
L10n::$locales['reported'] = 'envoyé';
|
||||||
|
L10n::$locales['Activity log'] = 'Journal d\'activité';
|
||||||
|
L10n::$locales['Log and receive your blog activity by email, feed, or on dashboard'] = 'Enregistrer et recevoir l\'activité de votre blog par mail, flux ou sur le tableau de bord';
|
@ -1,270 +1,398 @@
|
|||||||
|
# Language: Français
|
||||||
|
# Module: activityReport - 3.0
|
||||||
|
# Date: 2023-04-20 12:20:14
|
||||||
|
# Author: , contact@jcdenis.fr
|
||||||
|
# Translated with translater 2023.03.19
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Project-Id-Version: activityReport 2.0\n"
|
"Project-Id-Version: activityReport 3.0\n"
|
||||||
"POT-Creation-Date: \n"
|
"POT-Creation-Date: \n"
|
||||||
"PO-Revision-Date: 2022-11-27T21:29:52+00:00\n"
|
"PO-Revision-Date: 2023-04-20T12:20:14+00:00\n"
|
||||||
"Last-Translator: Jean-Crhistian Denis\n"
|
"Last-Translator: Jean-Christian Denis\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
msgid "Activity report"
|
#: src/ActivityBehaviors.php:32
|
||||||
msgstr "Rapport d'activité"
|
|
||||||
|
|
||||||
msgid "View all logs"
|
|
||||||
msgstr "Voir tous les logs"
|
|
||||||
|
|
||||||
msgid "Number of activities to show on dashboard:"
|
|
||||||
msgstr "Nombre d'activités à afficher sur le tableau de bord :"
|
|
||||||
|
|
||||||
msgid "Do not show activity report"
|
|
||||||
msgstr "Ne pas afficher le rapport d'activité"
|
|
||||||
|
|
||||||
msgid "every hour"
|
|
||||||
msgstr "toutes les heures"
|
|
||||||
|
|
||||||
msgid "every 2 hours"
|
|
||||||
msgstr "toutes les 2 heures"
|
|
||||||
|
|
||||||
msgid "2 times by day"
|
|
||||||
msgstr "2 fois par jour"
|
|
||||||
|
|
||||||
msgid "every day"
|
|
||||||
msgstr "tous les jours"
|
|
||||||
|
|
||||||
msgid "every 2 days"
|
|
||||||
msgstr "tous les 2 jours"
|
|
||||||
|
|
||||||
msgid "every week"
|
|
||||||
msgstr "toutes les semaines"
|
|
||||||
|
|
||||||
msgid "every 2 weeks"
|
|
||||||
msgstr "toutes les 2 semaines"
|
|
||||||
|
|
||||||
msgid "every 4 weeks"
|
|
||||||
msgstr "toutes les 4 semaines"
|
|
||||||
|
|
||||||
msgid "Plain text"
|
|
||||||
msgstr "Texte brut"
|
|
||||||
|
|
||||||
msgid "HTML"
|
|
||||||
msgstr "HTML"
|
|
||||||
|
|
||||||
msgid "Report successfully sent."
|
|
||||||
msgstr "Rapport envoyé avec succès."
|
|
||||||
|
|
||||||
msgid "Logs successfully deleted."
|
|
||||||
msgstr "Logs effacés avec succès."
|
|
||||||
|
|
||||||
msgid "never"
|
|
||||||
msgstr "jamais"
|
|
||||||
|
|
||||||
msgid "on new activity"
|
|
||||||
msgstr "lors d'une nouvelle activité"
|
|
||||||
|
|
||||||
msgid "Configure activity report for %s"
|
|
||||||
msgstr "Configurer le rapport d'activité pour %s"
|
|
||||||
|
|
||||||
msgid "current blog"
|
|
||||||
msgstr "le blog courant"
|
|
||||||
|
|
||||||
msgid "all blogs"
|
|
||||||
msgstr "tous les blogs"
|
|
||||||
|
|
||||||
msgid "This server has no mail function, activityReport does not send email report."
|
|
||||||
msgstr "Ce server n'a pas de fonction d'envoie de mail, le rapport ne sera pas envoyer."
|
|
||||||
|
|
||||||
msgid "Enable super administrator report"
|
|
||||||
msgstr "Autoriser le rapport de super administrateur"
|
|
||||||
|
|
||||||
msgid "Enable report on this blog"
|
|
||||||
msgstr "Autoriser le rapport sur ce blog"
|
|
||||||
|
|
||||||
msgid "Automatic cleaning of old logs:"
|
|
||||||
msgstr "Nettoyage automatique des anciennes activités:"
|
|
||||||
|
|
||||||
msgid "Use Dotclear date formaters. ex: %B %d at %H:%M"
|
|
||||||
msgstr "Utiliser le formatage des dates de Dotclear. ex: %d %B à %H:%M"
|
|
||||||
|
|
||||||
msgid "RSS feed"
|
|
||||||
msgstr "Flux RSS"
|
|
||||||
|
|
||||||
msgid "Rss2 feed for activity on this blog"
|
|
||||||
msgstr "Flux Rss2 pour l'activité de ce blog"
|
|
||||||
|
|
||||||
msgid "Atom feed"
|
|
||||||
msgstr "Flux Atom"
|
|
||||||
|
|
||||||
msgid "Atom feed for activity on this blog"
|
|
||||||
msgstr "Flux Atom pour l'activité de ce blog"
|
|
||||||
|
|
||||||
msgid "Send report:"
|
|
||||||
msgstr "Rapport envoyé :"
|
|
||||||
|
|
||||||
msgid "Recipients:"
|
|
||||||
msgstr "Destinataires :"
|
|
||||||
|
|
||||||
msgid "Separate multiple email addresses with a semicolon \";\""
|
|
||||||
msgstr "Séparer les adresses email par un point-virgule \";\""
|
|
||||||
|
|
||||||
msgid "Report format:"
|
|
||||||
msgstr "Format du rapport :"
|
|
||||||
|
|
||||||
msgid "Last report by email:"
|
|
||||||
msgstr "Dernier rapport par email :"
|
|
||||||
|
|
||||||
msgid "Next report by email:"
|
|
||||||
msgstr "Prochain rapport par email :"
|
|
||||||
|
|
||||||
msgid "Select blogs to add to report"
|
|
||||||
msgstr "Sélectionner les blogs à ajouter au rapport"
|
|
||||||
|
|
||||||
msgid "Report"
|
|
||||||
msgstr "Rapport"
|
|
||||||
|
|
||||||
msgid "Select actions by activity type to add to report"
|
|
||||||
msgstr "Sélectionner les actions par type d'activité à ajouter au rapport"
|
|
||||||
|
|
||||||
msgid "Send report now"
|
|
||||||
msgstr "Envoyer un rapport maintenant"
|
|
||||||
|
|
||||||
msgid "Delete all logs now"
|
|
||||||
msgstr "Effacer tous les logs maintenant"
|
|
||||||
|
|
||||||
msgid "ActivityReport messages"
|
msgid "ActivityReport messages"
|
||||||
msgstr "Messages de l'extension"
|
msgstr "Messages de l'extension"
|
||||||
|
|
||||||
msgid "Special messages"
|
#: src/ActivityBehaviors.php:33
|
||||||
msgstr "Messages spéciaux"
|
|
||||||
|
|
||||||
msgid "%s"
|
|
||||||
msgstr "%s"
|
|
||||||
|
|
||||||
msgid "Actions on blog"
|
msgid "Actions on blog"
|
||||||
msgstr "Actions sur le blog"
|
msgstr "Actions sur le blog"
|
||||||
|
|
||||||
msgid "updating blog"
|
#: src/ActivityBehaviors.php:34
|
||||||
msgstr "Mise à jour du blog"
|
|
||||||
|
|
||||||
msgid "Blog was updated by \"%s\""
|
|
||||||
msgstr "Blog mis à jour par \"%s\""
|
|
||||||
|
|
||||||
msgid "404 error"
|
|
||||||
msgstr "Erreur 404"
|
|
||||||
|
|
||||||
msgid "New 404 error page at \"%s\""
|
|
||||||
msgstr "Nouvelle erreur 404 à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "Actions on posts"
|
msgid "Actions on posts"
|
||||||
msgstr "Actions sur les billets"
|
msgstr "Actions sur les billets"
|
||||||
|
|
||||||
msgid "post creation"
|
#: src/ActivityBehaviors.php:35
|
||||||
msgstr "Création de billet"
|
|
||||||
|
|
||||||
msgid "A new post called \"%s\" was created by \"%s\" at %s"
|
|
||||||
msgstr "Un nouveau billet nommé \"%s\" a été créé par \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "updating post"
|
|
||||||
msgstr "Mise à jour de billet"
|
|
||||||
|
|
||||||
msgid "Post called \"%s\" has been updated by \"%s\" at %s"
|
|
||||||
msgstr "Le billet nommé \"%s\" a été mis à jour par \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "post deletion"
|
|
||||||
msgstr "Suppression de billet"
|
|
||||||
|
|
||||||
msgid "Post called \"%s\" has been deleted by \"%s\""
|
|
||||||
msgstr "Le billet nommé \"%s\" a été supprimé par \"%s\""
|
|
||||||
|
|
||||||
msgid "Post protection"
|
|
||||||
msgstr "Protection des billets"
|
|
||||||
|
|
||||||
msgid "An attempt failed on a passworded post with password \"%s\" at \"%s\""
|
|
||||||
msgstr "Une tentative a échoué sur un billet protégé par mot de passe avec l'essai \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "Actions on comments"
|
msgid "Actions on comments"
|
||||||
msgstr "Actions sur les commentaires"
|
msgstr "Actions sur les commentaires"
|
||||||
|
|
||||||
msgid "comment creation"
|
#: src/ActivityBehaviors.php:36
|
||||||
msgstr "Création de commentaire"
|
|
||||||
|
|
||||||
msgid "A new comment was created by \"%s\" on post \"%s\" at %s"
|
|
||||||
msgstr "Un nouveau commentaire a été créé par \"%s\" sur le billet \"%s\""
|
|
||||||
|
|
||||||
msgid "updating comment"
|
|
||||||
msgstr "Mise à jour de commentaire"
|
|
||||||
|
|
||||||
msgid "Comment has been updated by \"%s\" at %s"
|
|
||||||
msgstr "Un commentaire a été mise à jour par \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "trackback creation"
|
|
||||||
msgstr "Création de trackback"
|
|
||||||
|
|
||||||
msgid "A new trackback to \"%\" at \"%s\" was created on post \"%s\" at %s"
|
|
||||||
msgstr "Un nouveau rétrolien vers \"%s\" a été créé sur le billet \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "Actions on categories"
|
msgid "Actions on categories"
|
||||||
msgstr "Actions sur les catégories"
|
msgstr "Actions sur les catégories"
|
||||||
|
|
||||||
msgid "category creation"
|
#: src/ActivityBehaviors.php:37
|
||||||
msgstr "Création de catégorie"
|
|
||||||
|
|
||||||
msgid "A new category called \"%s\" was created by \"%s\" at %s"
|
|
||||||
msgstr "Un nouvelle catégorie nommée \"%s\" a été créé par \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "updating category"
|
|
||||||
msgstr "Mise à jour de catégorie"
|
|
||||||
|
|
||||||
msgid "Category called \"%s\" has been updated by \"%s\" at %s"
|
|
||||||
msgstr "La catégorie nommée \"%s\" a été mise à jour par \"%s\" à l'adresse \"%s\""
|
|
||||||
|
|
||||||
msgid "Actions on users"
|
msgid "Actions on users"
|
||||||
msgstr "Actions sur les utilisateurs"
|
msgstr "Actions sur les utilisateurs"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:43
|
||||||
|
msgid "Special messages"
|
||||||
|
msgstr "Messages spéciaux"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:44
|
||||||
|
msgid "%s"
|
||||||
|
msgstr "%s"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:54
|
||||||
|
msgid "updating blog"
|
||||||
|
msgstr "Mise à jour du blog"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:55
|
||||||
|
msgid "Blog was updated by \"%s\""
|
||||||
|
msgstr "Blog mis à jour par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:63
|
||||||
|
msgid "404 error"
|
||||||
|
msgstr "Erreur 404"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:64
|
||||||
|
msgid "New 404 error page at \"%s\""
|
||||||
|
msgstr "Nouvelle erreur 404 à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:74
|
||||||
|
msgid "post creation"
|
||||||
|
msgstr "Création de billet"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:75
|
||||||
|
msgid "A new post called \"%s\" was created by \"%s\" at %s"
|
||||||
|
msgstr "Un nouveau billet nommé \"%s\" a été créé par \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:94
|
||||||
|
msgid "updating post"
|
||||||
|
msgstr "Mise à jour de billet"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:95
|
||||||
|
msgid "Post called \"%s\" has been updated by \"%s\" at %s"
|
||||||
|
msgstr "Le billet nommé \"%s\" a été mis à jour par \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:103
|
||||||
|
msgid "post deletion"
|
||||||
|
msgstr "Suppression de billet"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:104
|
||||||
|
msgid "Post called \"%s\" has been deleted by \"%s\""
|
||||||
|
msgstr "Le billet nommé \"%s\" a été supprimé par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:113
|
||||||
|
msgid "Post protection"
|
||||||
|
msgstr "Protection des billets"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:114
|
||||||
|
msgid "An attempt failed on a passworded post with password \"%s\" at \"%s\""
|
||||||
|
msgstr "Une tentative a échoué sur un billet protégé par mot de passe avec l'essai \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:124
|
||||||
|
msgid "comment creation"
|
||||||
|
msgstr "Création de commentaire"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:125
|
||||||
|
msgid "A new comment was created by \"%s\" on post \"%s\" at %s"
|
||||||
|
msgstr "Un nouveau commentaire a été créé par \"%s\" sur le billet \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:134
|
||||||
|
msgid "updating comment"
|
||||||
|
msgstr "Mise à jour de commentaire"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:135
|
||||||
|
msgid "Comment has been updated by \"%s\" at %s"
|
||||||
|
msgstr "Un commentaire a été mise à jour par \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:147
|
||||||
|
msgid "trackback creation"
|
||||||
|
msgstr "Création de trackback"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:148
|
||||||
|
msgid "A new trackback to \"%\" at \"%s\" was created on post \"%s\" at %s"
|
||||||
|
msgstr "Un nouveau rétrolien vers \"%s\" a été créé sur le billet \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:156
|
||||||
|
msgid "category creation"
|
||||||
|
msgstr "Création de catégorie"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:157
|
||||||
|
msgid "A new category called \"%s\" was created by \"%s\" at %s"
|
||||||
|
msgstr "Un nouvelle catégorie nommée \"%s\" a été créé par \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:165
|
||||||
|
msgid "updating category"
|
||||||
|
msgstr "Mise à jour de catégorie"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:166
|
||||||
|
msgid "Category called \"%s\" has been updated by \"%s\" at %s"
|
||||||
|
msgstr "La catégorie nommée \"%s\" a été mise à jour par \"%s\" à l'adresse \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:176
|
||||||
msgid "user creation"
|
msgid "user creation"
|
||||||
msgstr "Création d'utilisateur"
|
msgstr "Création d'utilisateur"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:177
|
||||||
msgid "A new user named \"%s\" was created by \"%s\""
|
msgid "A new user named \"%s\" was created by \"%s\""
|
||||||
msgstr "Un nouvel utilisateur a été ajouté par \"%s\""
|
msgstr "Un nouvel utilisateur a été ajouté par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:185
|
||||||
msgid "updating user"
|
msgid "updating user"
|
||||||
msgstr "Mise à jour d'utilisateur"
|
msgstr "Mise à jour d'utilisateur"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:186
|
||||||
msgid "User named \"%s\" has been updated by \"%s\""
|
msgid "User named \"%s\" has been updated by \"%s\""
|
||||||
msgstr "L'utilisateur \"%s\" a été mis à jour par \"%s\""
|
msgstr "L'utilisateur \"%s\" a été mis à jour par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:217
|
||||||
msgid "user deletion"
|
msgid "user deletion"
|
||||||
msgstr "Suppression d'utilisateur"
|
msgstr "Suppression d'utilisateur"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:218
|
||||||
msgid "User named \"%s\" has been deleted by \"%\""
|
msgid "User named \"%s\" has been deleted by \"%\""
|
||||||
msgstr "L'utilisateur nommé \"%s\" a été supprimé par \"%s\""
|
msgstr "L'utilisateur nommé \"%s\" a été supprimé par \"%s\""
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:235
|
||||||
|
msgid "HTML"
|
||||||
|
msgstr "HTML"
|
||||||
|
|
||||||
|
#: src/ActivityBehaviors.php:248
|
||||||
|
#: src/ActivityReport.php:341
|
||||||
|
msgid "Activity report"
|
||||||
|
msgstr "Rapport d'activité"
|
||||||
|
|
||||||
|
#: src/ActivityReport.php:331
|
||||||
msgid "An error occured when parsing report."
|
msgid "An error occured when parsing report."
|
||||||
msgstr "Une erreur est survenue lors de la compilation du rapport."
|
msgstr "Une erreur est survenue lors de la compilation du rapport."
|
||||||
|
|
||||||
|
#: src/ActivityReport.php:347
|
||||||
msgid "You received a message from your blog's activity report module."
|
msgid "You received a message from your blog's activity report module."
|
||||||
msgstr "Vous recevez un message du module de rapport d'activité de votre blog."
|
msgstr "Vous recevez un message du module de rapport d'activité de votre blog."
|
||||||
|
|
||||||
|
#: src/ActivityReport.php:356
|
||||||
msgid "Period from %s to %s"
|
msgid "Period from %s to %s"
|
||||||
msgstr "Période du %s au %s"
|
msgstr "Période du %s au %s"
|
||||||
|
|
||||||
|
#: src/ActivityReport.php:404
|
||||||
msgid "Activity report deletes some old logs."
|
msgid "Activity report deletes some old logs."
|
||||||
msgstr "L'extension a automatiquement effacé des anciennes activités."
|
msgstr "L'extension a automatiquement effacé des anciennes activités."
|
||||||
|
|
||||||
msgid "Blog activity report"
|
#: src/ActivityReport.php:661
|
||||||
msgstr "Rapport d'activité du blog"
|
msgid "Blog \"%s\" activity report"
|
||||||
|
msgstr "Rapport d'activité du blog \"%s\""
|
||||||
|
|
||||||
msgid "Logs"
|
#: src/Backend.php:126
|
||||||
msgstr "Enregistrements"
|
msgid "View all logs"
|
||||||
|
msgstr "Voir tous les logs"
|
||||||
|
|
||||||
|
#: src/Backend.php:142
|
||||||
|
msgid "Number of activities to show on dashboard:"
|
||||||
|
msgstr "Nombre d'activités à afficher sur le tableau de bord :"
|
||||||
|
|
||||||
|
#: src/Backend.php:144
|
||||||
|
msgid "Do not show activity report"
|
||||||
|
msgstr "Ne pas afficher le rapport d'activité"
|
||||||
|
|
||||||
|
#: src/Backend.php:170
|
||||||
|
#: src/ManageList.php:48
|
||||||
|
msgid "Group"
|
||||||
|
msgstr "Groupe"
|
||||||
|
|
||||||
|
#: src/Backend.php:177
|
||||||
|
msgid "logs per page"
|
||||||
|
msgstr "enregistrements par page"
|
||||||
|
|
||||||
|
#: src/Combo.php:45
|
||||||
|
msgid "every hour"
|
||||||
|
msgstr "toutes les heures"
|
||||||
|
|
||||||
|
#: src/Combo.php:46
|
||||||
|
msgid "every 2 hours"
|
||||||
|
msgstr "toutes les 2 heures"
|
||||||
|
|
||||||
|
#: src/Combo.php:47
|
||||||
|
msgid "2 times by day"
|
||||||
|
msgstr "2 fois par jour"
|
||||||
|
|
||||||
|
#: src/Combo.php:48
|
||||||
|
msgid "every day"
|
||||||
|
msgstr "tous les jours"
|
||||||
|
|
||||||
|
#: src/Combo.php:49
|
||||||
|
msgid "every 2 days"
|
||||||
|
msgstr "tous les 2 jours"
|
||||||
|
|
||||||
|
#: src/Combo.php:50
|
||||||
|
msgid "every week"
|
||||||
|
msgstr "toutes les semaines"
|
||||||
|
|
||||||
|
#: src/Combo.php:68
|
||||||
|
msgid "every 2 weeks"
|
||||||
|
msgstr "toutes les 2 semaines"
|
||||||
|
|
||||||
|
#: src/Combo.php:69
|
||||||
|
msgid "every 4 weeks"
|
||||||
|
msgstr "toutes les 4 semaines"
|
||||||
|
|
||||||
|
#: src/Config.php:85
|
||||||
|
msgid "Report successfully sent."
|
||||||
|
msgstr "Rapport envoyé avec succès."
|
||||||
|
|
||||||
|
#: src/Config.php:92
|
||||||
|
msgid "Logs successfully deleted."
|
||||||
|
msgstr "Logs effacés avec succès."
|
||||||
|
|
||||||
|
#: src/Config.php:116
|
||||||
|
msgid "never"
|
||||||
|
msgstr "jamais"
|
||||||
|
|
||||||
|
#: src/Config.php:117
|
||||||
|
msgid "on new activity"
|
||||||
|
msgstr "lors d'une nouvelle activité"
|
||||||
|
|
||||||
|
#: src/Config.php:133
|
||||||
|
msgid "This server has no mail function, activityReport does not send email report."
|
||||||
|
msgstr "Ce server n'a pas de fonction d'envoie de mail, le rapport ne sera pas envoyer."
|
||||||
|
|
||||||
|
#: src/Config.php:140
|
||||||
|
msgid "Mail report"
|
||||||
|
msgstr "Rapport par email"
|
||||||
|
|
||||||
|
#: src/Config.php:142
|
||||||
|
msgid "Send report:"
|
||||||
|
msgstr "Rapport envoyé :"
|
||||||
|
|
||||||
|
#: src/Config.php:146
|
||||||
|
msgid "Recipients:"
|
||||||
|
msgstr "Destinataires :"
|
||||||
|
|
||||||
|
#: src/Config.php:149
|
||||||
|
msgid "Separate multiple email addresses with a semicolon \";\""
|
||||||
|
msgstr "Séparer les adresses email par un point-virgule \";\""
|
||||||
|
|
||||||
|
#: src/Config.php:150
|
||||||
|
msgid "Leave it empty to disable mail report."
|
||||||
|
msgstr "Laisser vide pour désactiver le rapport par email."
|
||||||
|
|
||||||
|
#: src/Config.php:155
|
||||||
|
msgid "Use Dotclear date formaters. ex: %B %d at %H:%M"
|
||||||
|
msgstr "Utiliser le formatage des dates de Dotclear. ex: %d %B à %H:%M"
|
||||||
|
|
||||||
|
#: src/Config.php:157
|
||||||
|
msgid "Report format:"
|
||||||
|
msgstr "Format du rapport :"
|
||||||
|
|
||||||
|
#: src/Config.php:162
|
||||||
|
msgid "Last report by email:"
|
||||||
|
msgstr "Dernier rapport par email :"
|
||||||
|
|
||||||
|
#: src/Config.php:163
|
||||||
|
msgid "Next report by email:"
|
||||||
|
msgstr "Prochain rapport par email :"
|
||||||
|
|
||||||
|
#: src/Config.php:167
|
||||||
|
msgid "Feeds"
|
||||||
|
msgstr "Flux"
|
||||||
|
|
||||||
|
#: src/Config.php:170
|
||||||
|
msgid "Enable activity feed"
|
||||||
|
msgstr "Activer le flux d'activités"
|
||||||
|
|
||||||
|
#: src/Config.php:174
|
||||||
|
msgid "RSS feed"
|
||||||
|
msgstr "Flux RSS"
|
||||||
|
|
||||||
|
#: src/Config.php:177
|
||||||
|
msgid "Rss2 activities feed"
|
||||||
|
msgstr "Flux RSS2 d'activités"
|
||||||
|
|
||||||
|
#: src/Config.php:178
|
||||||
|
msgid "Atom feed"
|
||||||
|
msgstr "Flux Atom"
|
||||||
|
|
||||||
|
#: src/Config.php:181
|
||||||
|
msgid "Atom activities feed"
|
||||||
|
msgstr "Flux Atom d'activités"
|
||||||
|
|
||||||
|
#: src/Config.php:188
|
||||||
|
msgid "Activities"
|
||||||
|
msgstr "Activités"
|
||||||
|
|
||||||
|
#: src/Config.php:189
|
||||||
|
msgid "Select actions by activity type to add to report"
|
||||||
|
msgstr "Sélectionner les actions par type d'activité à ajouter au rapport"
|
||||||
|
|
||||||
|
#: src/Config.php:214
|
||||||
|
msgid "Automatic cleaning of old logs:"
|
||||||
|
msgstr "Nettoyage automatique des anciennes activités:"
|
||||||
|
|
||||||
|
#: src/Config.php:219
|
||||||
|
msgid "Send report now"
|
||||||
|
msgstr "Envoyer un rapport maintenant"
|
||||||
|
|
||||||
|
#: src/Config.php:223
|
||||||
|
msgid "Delete all logs now"
|
||||||
|
msgstr "Effacer tous les logs maintenant"
|
||||||
|
|
||||||
|
#: src/Format.php:68
|
||||||
|
msgid "Plain text"
|
||||||
|
msgstr "Texte brut"
|
||||||
|
|
||||||
|
#: src/Manage.php:58
|
||||||
|
msgid "Logs successfully deleted"
|
||||||
|
msgstr "Enregistrements effacés avec succès"
|
||||||
|
|
||||||
|
#: src/Manage.php:91
|
||||||
|
msgid "Are you sure you want to delete logs?"
|
||||||
|
msgstr "Êtes-vous sure de vouloir effacer les enregistrements ?"
|
||||||
|
|
||||||
|
#: src/Manage.php:114
|
||||||
|
msgid "Delete all aticivity logs"
|
||||||
|
msgstr "Effacer tous les enregistrements d'activités"
|
||||||
|
|
||||||
|
#: src/Manage.php:115
|
||||||
|
msgid "Delete all allready reported logs"
|
||||||
|
msgstr "Effacer les enregistrements d'activités déjà envoyé par email"
|
||||||
|
|
||||||
|
#: src/ManageList.php:33
|
||||||
|
msgid "No log matches the filter"
|
||||||
|
msgstr "Aucun enregistrement ne correspond au filtre"
|
||||||
|
|
||||||
|
#: src/ManageList.php:35
|
||||||
msgid "No log"
|
msgid "No log"
|
||||||
msgstr "Pas d'enregistrement"
|
msgstr "Pas d'enregistrement"
|
||||||
|
|
||||||
|
#: src/ManageList.php:43
|
||||||
|
msgid "List of %s logs matching the filter."
|
||||||
|
msgstr "Liste des %s logs correspondants au filtre."
|
||||||
|
|
||||||
|
#: src/ManageList.php:44
|
||||||
|
msgid "List of %s logs."
|
||||||
|
msgstr "Listes des %s enregistrements"
|
||||||
|
|
||||||
|
#: src/ManageList.php:50
|
||||||
msgid "Message"
|
msgid "Message"
|
||||||
msgstr "Message"
|
msgstr "Message"
|
||||||
|
|
||||||
msgid "Activity report module"
|
#: src/ManageList.php:79
|
||||||
msgstr "Module de rapport d'activité"
|
msgid "undefined"
|
||||||
|
msgstr "inconnu"
|
||||||
|
|
||||||
|
#: src/ManageList.php:85
|
||||||
|
msgid "reported"
|
||||||
|
msgstr "envoyé"
|
||||||
|
|
||||||
|
msgid "Activity log"
|
||||||
|
msgstr "Journal d'activité"
|
||||||
|
|
||||||
|
msgid "Log and receive your blog activity by email, feed, or on dashboard"
|
||||||
|
msgstr "Enregistrer et recevoir l'activité de votre blog par mail, flux ou sur le tableau de bord"
|
||||||
|
|
||||||
|
45
src/Action.php
Normal file
45
src/Action.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action descriptor.
|
||||||
|
*/
|
||||||
|
class Action
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Constructor sets action description.
|
||||||
|
*
|
||||||
|
* @param string $id The action ID
|
||||||
|
* @param string $title The action title
|
||||||
|
* @param string $message The action message
|
||||||
|
* @param string $behavior The behavior name
|
||||||
|
* @param null|callable $function The callback function
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public readonly string $id,
|
||||||
|
public readonly string $title,
|
||||||
|
public readonly string $message,
|
||||||
|
string $behavior,
|
||||||
|
?callable $function
|
||||||
|
) {
|
||||||
|
// fake action has no behavior
|
||||||
|
if (null !== $function) {
|
||||||
|
dcCore::app()->addBehavior($behavior, $function);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,393 +10,470 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
namespace Dotclear\Plugin\activityReport;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
class activityReportBehaviors
|
use ArrayObject;
|
||||||
|
use cursor;
|
||||||
|
use dcBlog;
|
||||||
|
use dcCore;
|
||||||
|
use dcRecord;
|
||||||
|
use dcUtils;
|
||||||
|
use Dotclear\Helper\Network\Http;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register default activities and export mail formats.
|
||||||
|
*/
|
||||||
|
class ActivityBehaviors
|
||||||
{
|
{
|
||||||
public static function registerBehaviors()
|
public static function register(): void
|
||||||
{
|
{
|
||||||
// ActivityReport plugin
|
$my = new Group(My::id(), __('ActivityReport messages'));
|
||||||
dcCore::app()->activityReport->addGroup(basename(dirname(__DIR__)), __('ActivityReport messages'));
|
$blog = new Group('blog', __('Actions on blog'));
|
||||||
|
$post = new Group('post', __('Actions on posts'));
|
||||||
|
$comment = new Group('comment', __('Actions on comments'));
|
||||||
|
$category = new Group('category', __('Actions on categories'));
|
||||||
|
$user = new Group('user', __('Actions on users'));
|
||||||
|
|
||||||
dcCore::app()->activityReport->addAction(
|
// ActivityReport plugin
|
||||||
basename(dirname(__DIR__)),
|
|
||||||
|
$my->add(new Action(
|
||||||
'message',
|
'message',
|
||||||
__('Special messages'),
|
__('Special messages'),
|
||||||
__('%s'),
|
__('%s'),
|
||||||
'messageActivityReport',
|
'messageActivityReport',
|
||||||
['activityReportBehaviors', 'messageActivityReport']
|
[self::class, 'messageActivityReport']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Blog
|
|
||||||
dcCore::app()->activityReport->addGroup('blog', __('Actions on blog'));
|
|
||||||
|
|
||||||
// Not use as it is global : BEHAVIOR adminAfterBlogCreate in admin/blog.php
|
// Not use as it is global : BEHAVIOR adminAfterBlogCreate in admin/blog.php
|
||||||
|
|
||||||
// from BEHAVIOR adminAfterBlogUpdate in admin/blog_pref.php
|
// from BEHAVIOR adminAfterBlogUpdate in admin/blog_pref.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$blog->add(new Action(
|
||||||
'blog',
|
|
||||||
'update',
|
'update',
|
||||||
__('updating blog'),
|
__('updating blog'),
|
||||||
__('Blog was updated by "%s"'),
|
__('Blog was updated by "%s"'),
|
||||||
'adminAfterBlogUpdate',
|
'adminAfterBlogUpdate',
|
||||||
['activityReportBehaviors', 'blogUpdate']
|
[self::class, 'blogUpdate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR publicHeadContent in template
|
// from BEHAVIOR publicHeadContent in template
|
||||||
dcCore::app()->activityReport->addAction(
|
$blog->add(new Action(
|
||||||
'blog',
|
|
||||||
'p404',
|
'p404',
|
||||||
__('404 error'),
|
__('404 error'),
|
||||||
__('New 404 error page at "%s"'),
|
__('New 404 error page at "%s"'),
|
||||||
'publicHeadContent',
|
'publicHeadContent',
|
||||||
['activityReportBehaviors', 'blogP404']
|
[self::class, 'blogP404']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Post
|
|
||||||
dcCore::app()->activityReport->addGroup('post', __('Actions on posts'));
|
|
||||||
|
|
||||||
// from BEHAVIOR coreAfterPostCreate in inc/core/class.dc.blog.php (DC 2.2)
|
// from BEHAVIOR coreAfterPostCreate in inc/core/class.dc.blog.php (DC 2.2)
|
||||||
// duplicate adminAfterPostCreate in admin/post.php
|
// duplicate adminAfterPostCreate in admin/post.php
|
||||||
// duplicate adminAfterPostCreate in admin/services.php
|
// duplicate adminAfterPostCreate in admin/services.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$post->add(new Action(
|
||||||
'post',
|
|
||||||
'create',
|
'create',
|
||||||
__('post creation'),
|
__('post creation'),
|
||||||
__('A new post called "%s" was created by "%s" at %s'),
|
__('A new post called "%s" was created by "%s" at %s'),
|
||||||
'adminAfterPostCreate',
|
'adminAfterPostCreate',
|
||||||
['activityReportBehaviors', 'postCreate']
|
[self::class, 'postCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Plugin contribute
|
// Plugin contribute
|
||||||
// from BEHAVIOR publicAfterPostCreate in plugins/contribute/_public.php
|
// from BEHAVIOR publicAfterPostCreate in plugins/contribute/_public.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$post->add(new Action(
|
||||||
'post',
|
|
||||||
'create',
|
'create',
|
||||||
__('post creation'),
|
__('post creation'),
|
||||||
__('A new post called "%s" was created by "%s" at %s'),
|
__('A new post called "%s" was created by "%s" at %s'),
|
||||||
'publicAfterPostCreate',
|
'publicAfterPostCreate',
|
||||||
['activityReportBehaviors', 'postCreate']
|
[self::class, 'postCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR coreAfterPostUpdate in inc/core/class.dc.blog.php (DC2.2)
|
// from BEHAVIOR coreAfterPostUpdate in inc/core/class.dc.blog.php (DC2.2)
|
||||||
// duplicate adminAfterPostUpdate in admin/post.php
|
// duplicate adminAfterPostUpdate in admin/post.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$post->add(new Action(
|
||||||
'post',
|
|
||||||
'update',
|
'update',
|
||||||
__('updating post'),
|
__('updating post'),
|
||||||
__('Post called "%s" has been updated by "%s" at %s'),
|
__('Post called "%s" has been updated by "%s" at %s'),
|
||||||
'adminAfterPostUpdate',
|
'adminAfterPostUpdate',
|
||||||
['activityReportBehaviors', 'postUpdate']
|
[self::class, 'postUpdate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR adminBeforePostDelete in admin/post.php
|
// from BEHAVIOR adminBeforePostDelete in admin/post.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$post->add(new Action(
|
||||||
'post',
|
|
||||||
'delete',
|
'delete',
|
||||||
__('post deletion'),
|
__('post deletion'),
|
||||||
__('Post called "%s" has been deleted by "%s"'),
|
__('Post called "%s" has been deleted by "%s"'),
|
||||||
'adminBeforePostDelete',
|
'adminBeforePostDelete',
|
||||||
['activityReportBehaviors', 'postDelete']
|
[self::class, 'postDelete']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Wrong attempt on passworded enrty
|
// Wrong attempt on passworded enrty
|
||||||
// from BEHAVIOR urlHandlerServeDocument in inc/public/lib.urlhandlers.php
|
// from BEHAVIOR urlHandlerServeDocument in inc/public/lib.urlhandlers.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$post->add(new Action(
|
||||||
'post',
|
|
||||||
'protection',
|
'protection',
|
||||||
__('Post protection'),
|
__('Post protection'),
|
||||||
__('An attempt failed on a passworded post with password "%s" at "%s"'),
|
__('An attempt failed on a passworded post with password "%s" at "%s"'),
|
||||||
'urlHandlerServeDocument',
|
'urlHandlerServeDocument',
|
||||||
['activityReportBehaviors', 'postPasswordAttempt']
|
[self::class, 'postPasswordAttempt']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Comment
|
|
||||||
dcCore::app()->activityReport->addGroup('comment', __('Actions on comments'));
|
|
||||||
|
|
||||||
// from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php
|
// from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php
|
||||||
// duplicate adminAfterCommentCreate in admin/comment.php
|
// duplicate adminAfterCommentCreate in admin/comment.php
|
||||||
// duplicate publicAfterCommentCreate in inc/public/lib.urlhandlers.php
|
// duplicate publicAfterCommentCreate in inc/public/lib.urlhandlers.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$comment->add(new Action(
|
||||||
'comment',
|
|
||||||
'create',
|
'create',
|
||||||
__('comment creation'),
|
__('comment creation'),
|
||||||
__('A new comment was created by "%s" on post "%s" at %s'),
|
__('A new comment was created by "%s" on post "%s" at %s'),
|
||||||
'coreAfterCommentCreate',
|
'coreAfterCommentCreate',
|
||||||
['activityReportBehaviors', 'commentCreate']
|
[self::class, 'commentCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR coreAfterCommentUpdate in inc/core/class.dc.blog.php
|
// from BEHAVIOR coreAfterCommentUpdate in inc/core/class.dc.blog.php
|
||||||
// duplicate adminAfterCommentUpdate in admin/comment.php
|
// duplicate adminAfterCommentUpdate in admin/comment.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$comment->add(new Action(
|
||||||
'comment',
|
|
||||||
'update',
|
'update',
|
||||||
__('updating comment'),
|
__('updating comment'),
|
||||||
__('Comment has been updated by "%s" at %s'),
|
__('Comment has been updated by "%s" at %s'),
|
||||||
'coreAfterCommentUpdate',
|
'coreAfterCommentUpdate',
|
||||||
['activityReportBehaviors', 'commentUpdate']
|
[self::class, 'commentUpdate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Missing coreBeforeCommentDelete in inc/core/class.dc.blog.php
|
// Missing coreBeforeCommentDelete in inc/core/class.dc.blog.php
|
||||||
// Missing adminBeforeCommentDelete in admin/comment.php
|
// Missing adminBeforeCommentDelete in admin/comment.php
|
||||||
|
|
||||||
// from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php
|
// from BEHAVIOR coreAfterCommentCreate in inc/core/class.dc.blog.php
|
||||||
// duplicate publicAfterTrackbackCreate in inc/core/class.dc.trackback.php
|
// duplicate publicAfterTrackbackCreate in inc/core/class.dc.trackback.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$comment->add(new Action(
|
||||||
'comment',
|
|
||||||
'trackback',
|
'trackback',
|
||||||
__('trackback creation'),
|
__('trackback creation'),
|
||||||
__('A new trackback to "%" at "%s" was created on post "%s" at %s'),
|
__('A new trackback to "%" at "%s" was created on post "%s" at %s'),
|
||||||
'coreAfterCommentCreate',
|
'coreAfterCommentCreate',
|
||||||
['activityReportBehaviors', 'trackbackCreate']
|
[self::class, 'trackbackCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Category
|
|
||||||
dcCore::app()->activityReport->addGroup('category', __('Actions on categories'));
|
|
||||||
|
|
||||||
// from BEHAVIOR adminAfterCategoryCreate in admin/category.php
|
// from BEHAVIOR adminAfterCategoryCreate in admin/category.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$category->add(new Action(
|
||||||
'category',
|
|
||||||
'create',
|
'create',
|
||||||
__('category creation'),
|
__('category creation'),
|
||||||
__('A new category called "%s" was created by "%s" at %s'),
|
__('A new category called "%s" was created by "%s" at %s'),
|
||||||
'adminAfterCategoryCreate',
|
'adminAfterCategoryCreate',
|
||||||
['activityReportBehaviors', 'categoryCreate']
|
[self::class, 'categoryCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR adminAfterCategoryUpdate in admin/category.php
|
// from BEHAVIOR adminAfterCategoryUpdate in admin/category.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$category->add(new Action(
|
||||||
'category',
|
|
||||||
'update',
|
'update',
|
||||||
__('updating category'),
|
__('updating category'),
|
||||||
__('Category called "%s" has been updated by "%s" at %s'),
|
__('Category called "%s" has been updated by "%s" at %s'),
|
||||||
'adminAfterCategoryUpdate',
|
'adminAfterCategoryUpdate',
|
||||||
['activityReportBehaviors', 'categoryUpdate']
|
[self::class, 'categoryUpdate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// Missing adminBeforeCategoryDelete in admin/category.php
|
// Missing adminBeforeCategoryDelete in admin/category.php
|
||||||
|
|
||||||
// User
|
|
||||||
dcCore::app()->activityReport->addGroup('user', __('Actions on users'));
|
|
||||||
|
|
||||||
// from BEHAVIOR adminAfterUserCreate in admin/user.php
|
// from BEHAVIOR adminAfterUserCreate in admin/user.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$user->add(new Action(
|
||||||
'user',
|
|
||||||
'create',
|
'create',
|
||||||
__('user creation'),
|
__('user creation'),
|
||||||
__('A new user named "%s" was created by "%s"'),
|
__('A new user named "%s" was created by "%s"'),
|
||||||
'adminAfterUserCreate',
|
'adminAfterUserCreate',
|
||||||
['activityReportBehaviors', 'userCreate']
|
[self::class, 'userCreate']
|
||||||
);
|
));
|
||||||
|
|
||||||
// from BEHAVIOR adminAfterUserUpdated in admin/user.php
|
// from BEHAVIOR adminAfterUserUpdated in admin/user.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$user->add(new Action(
|
||||||
'user',
|
|
||||||
'update',
|
'update',
|
||||||
__('updating user'),
|
__('updating user'),
|
||||||
__('User named "%s" has been updated by "%s"'),
|
__('User named "%s" has been updated by "%s"'),
|
||||||
'adminAfterUserUpdate',
|
'adminAfterUserUpdate',
|
||||||
['activityReportBehaviors', 'userUpdate']
|
[self::class, 'userUpdate']
|
||||||
);
|
));
|
||||||
|
|
||||||
|
// from BEHAVIOR adminAfterUserProfileUpdate in admin/preferences.php
|
||||||
|
$user->add(new Action(
|
||||||
|
'preference',
|
||||||
|
__('updating user preference'),
|
||||||
|
__('User named "%s" preference has been updated by "%s"'),
|
||||||
|
'adminAfterUserProfileUpdate',
|
||||||
|
[self::class, 'userPreference']
|
||||||
|
));
|
||||||
|
$user->add(new Action(
|
||||||
|
'preference',
|
||||||
|
__('updating user preference'),
|
||||||
|
__('User named "%s" preference has been updated by "%s"'),
|
||||||
|
'adminAfterUserOptionsUpdate',
|
||||||
|
[self::class, 'userPreference']
|
||||||
|
));
|
||||||
|
$user->add(new Action(
|
||||||
|
'preference',
|
||||||
|
__('updating user preference'),
|
||||||
|
__('User named "%s" preference has been updated by "%s"'),
|
||||||
|
'adminAfterDashboardOptionsUpdate',
|
||||||
|
[self::class, 'userPreference']
|
||||||
|
));
|
||||||
|
|
||||||
// from BEHAVIOR adminBeforeUserDelete in admin/users.php
|
// from BEHAVIOR adminBeforeUserDelete in admin/users.php
|
||||||
dcCore::app()->activityReport->addAction(
|
$user->add(new Action(
|
||||||
'user',
|
|
||||||
'delete',
|
'delete',
|
||||||
__('user deletion'),
|
__('user deletion'),
|
||||||
__('User named "%s" has been deleted by "%"'),
|
__('User named "%s" has been deleted by "%"'),
|
||||||
'adminBeforeUserDelete',
|
'adminBeforeUserDelete',
|
||||||
['activityReportBehaviors', 'userDelete']
|
[self::class, 'userDelete']
|
||||||
);
|
));
|
||||||
|
|
||||||
|
ActivityReport::instance()->groups
|
||||||
|
->add($my)
|
||||||
|
->add($blog)
|
||||||
|
->add($post)
|
||||||
|
->add($comment)
|
||||||
|
->add($category)
|
||||||
|
->add($user);
|
||||||
|
|
||||||
|
// Add default email report formats
|
||||||
|
ActivityReport::instance()->formats
|
||||||
|
->add(new Format('plain', [])) // plain text format is build with default values
|
||||||
|
->add(new Format('html', [
|
||||||
|
'name' => __('HTML'),
|
||||||
|
'blog_title' => '<h2><a href="%URL%">%TEXT%</a></h2>',
|
||||||
|
'group_title' => '<h3>%TEXT%</h3>',
|
||||||
|
'group_open' => '<ul>',
|
||||||
|
'group_close' => '</ul>',
|
||||||
|
'action' => '<li><em>%TIME%</em><br />%TEXT%</li>',
|
||||||
|
'error' => '<p>%TEXT%</p>',
|
||||||
|
'period_title' => '<h1>%TEXT%</h1>',
|
||||||
|
'period_open' => '<ul>',
|
||||||
|
'period_close' => '</ul>',
|
||||||
|
'info' => '<li>%TEXT%</li>',
|
||||||
|
'page' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n" .
|
||||||
|
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n" .
|
||||||
|
'<head><title>' . __('Activity report') . '</title>' .
|
||||||
|
'<style type="text/css">' .
|
||||||
|
' body { color: #303030; background: #FCFCFC; font-size: 0.7em;font-family: Georgia, Tahoma, Arial, Helvetica, sans-serif; }' .
|
||||||
|
' a { color: #303030; text-decoration: none; }' .
|
||||||
|
' h1 { text-align: center; font-size: 2em; }' .
|
||||||
|
' h2 { color: #303030; text-align:center; }' .
|
||||||
|
' h3 { color: #7F3F3F; }' .
|
||||||
|
' li em { color: #303030; }' .
|
||||||
|
' div.info { color: #3F497F; background-color: #F8F8EB; border: 1px solid #888888; margin: 4px; padding: 4px; }' .
|
||||||
|
' div.content { color: #3F7F47; background-color: #F8F8EB; border: 1px solid #888888; margin: 4px; padding: 4px; }' .
|
||||||
|
' div.foot { text-align:center; font-size: 0.9em; }' .
|
||||||
|
'</style>' .
|
||||||
|
'</head><body>' .
|
||||||
|
'<div class="info">%PERIOD%</div><div class="content">%TEXT%</div>' .
|
||||||
|
'<div class="foot"><p>Powered by <a href="https://github.com/JcDenis/activityReport">activityReport</a></p></div>' .
|
||||||
|
'</body></html>',
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function messageActivityReport($message)
|
public static function messageActivityReport(string $message): void
|
||||||
{
|
{
|
||||||
$logs = [$message];
|
$logs = [$message];
|
||||||
dcCore::app()->activityReport->addLog(basename(dirname(__DIR__)), 'message', $logs);
|
ActivityReport::instance()->addLog(My::id(), 'message', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function blogUpdate($cur, $blog_id)
|
public static function blogUpdate(cursor $cur, string $blog_id): void
|
||||||
{
|
{
|
||||||
$logs = [dcCore::app()->auth->getInfo('user_cn')];
|
$logs = [(string) dcCore::app()->auth?->getInfo('user_cn')];
|
||||||
dcCore::app()->activityReport->addLog('blog', 'update', $logs);
|
ActivityReport::instance()->addLog('blog', 'update', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function blogP404()
|
public static function blogP404(): void
|
||||||
{
|
{
|
||||||
if (dcCore::app()->url->type != '404') {
|
if (dcCore::app()->url->type != '404') {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
$logs = [dcCore::app()->blog->url . $_SERVER['QUERY_STRING']];
|
$logs = [(string) dcCore::app()->blog?->url . $_SERVER['QUERY_STRING']];
|
||||||
dcCore::app()->activityReport->addLog('blog', 'p404', $logs);
|
ActivityReport::instance()->addLog('blog', 'p404', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postCreate($cur, $post_id)
|
public static function postCreate(cursor $cur, int $post_id): void
|
||||||
{
|
{
|
||||||
$type = $cur->post_type ? $cur->post_type : 'post';
|
$type = $cur->getField('post_type') ?? 'post';
|
||||||
$post_url = dcCore::app()->blog->getPostURL('', $cur->post_dt, $cur->post_title, $post_id);
|
$post_url = dcCore::app()->blog?->getPostURL('', $cur->getField('post_dt'), $cur->getField('post_title'), $post_id);
|
||||||
$logs = [
|
$logs = [
|
||||||
$cur->post_title,
|
(string) $cur->getField('post_title'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase($type) . '/' . $post_url,
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase($type) . '/' . $post_url,
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('post', 'create', $logs);
|
ActivityReport::instance()->addLog('post', 'create', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postUpdate($cur, $post_id)
|
public static function postUpdate(cursor $cur, int $post_id): void
|
||||||
{
|
{
|
||||||
$type = $cur->post_type ? $cur->post_type : 'post';
|
$type = $cur->getField('post_type') ?? 'post';
|
||||||
$post_url = dcCore::app()->blog->getPostURL('', $cur->post_dt, $cur->post_title, $post_id);
|
$post_url = dcCore::app()->blog?->getPostURL('', $cur->getField('post_dt'), $cur->getField('post_title'), $post_id);
|
||||||
$logs = [
|
$logs = [
|
||||||
$cur->post_title,
|
(string) $cur->getField('post_title'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase($type) . '/' . $post_url,
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase($type) . '/' . $post_url,
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('post', 'update', $logs);
|
ActivityReport::instance()->addLog('post', 'update', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postDelete($post_id)
|
public static function postDelete(int $post_id): void
|
||||||
{
|
{
|
||||||
$posts = dcCore::app()->blog->getPosts(['post_id' => $post_id, 'limit' => 1]);
|
$posts = dcCore::app()->blog?->getPosts(['post_id' => $post_id, 'limit' => 1]);
|
||||||
$logs = [
|
if (!$posts || $posts->isEmpty()) {
|
||||||
$posts->post_title,
|
return;
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
}
|
||||||
|
$logs = [
|
||||||
|
(string) $posts->f('post_title'),
|
||||||
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('post', 'delete', $logs);
|
ActivityReport::instance()->addLog('post', 'delete', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function postPasswordAttempt($result)
|
public static function postPasswordAttempt(ArrayObject $result): void
|
||||||
{
|
{
|
||||||
if ($result['tpl'] != 'password-form.html' || empty($_POST['password'])) {
|
if ($result['tpl'] != 'password-form.html' || empty($_POST['password'])) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
$logs = [
|
$logs = [
|
||||||
$_POST['password'],
|
$_POST['password'],
|
||||||
http::getSelfURI(),
|
Http::getSelfURI(),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('post', 'protection', $logs);
|
ActivityReport::instance()->addLog('post', 'protection', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function commentCreate($blog, $cur)
|
public static function commentCreate(dcBlog $blog, cursor $cur): void
|
||||||
{
|
{
|
||||||
if ($cur->comment_trackback) {
|
if ($cur->getField('comment_trackback')) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
$posts = dcCore::app()->blog->getPosts(['post_id' => $cur->post_id, 'limit' => 1]);
|
$posts = dcCore::app()->blog?->getPosts(
|
||||||
$logs = [
|
['post_id' => $cur->getField('post_id'), 'limit' => 1, 'post_type' => '']
|
||||||
$cur->comment_author,
|
|
||||||
$posts->post_title,
|
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase($posts->post_type) .
|
|
||||||
'/' . $posts->post_url . '#c' . $cur->comment_id,
|
|
||||||
];
|
|
||||||
dcCore::app()->activityReport->addLog('comment', 'create', $logs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function commentUpdate($blog, $cur, $old)
|
|
||||||
{
|
|
||||||
$posts = dcCore::app()->blog->getPosts(['post_id' => $old->post_id, 'limit' => 1]);
|
|
||||||
|
|
||||||
$logs = [
|
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
|
||||||
$posts->post_title,
|
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase($posts->post_type) .
|
|
||||||
'/' . $posts->post_url . '#c' . $old->comment_id,
|
|
||||||
];
|
|
||||||
dcCore::app()->activityReport->addLog('comment', 'update', $logs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function trackbackCreate($cur, $comment_id)
|
|
||||||
{
|
|
||||||
// From blog args are $blog, $cur #thks to bruno
|
|
||||||
$c = $cur instanceof dcBlog ? $comment_id : $cur;
|
|
||||||
if (!$c->comment_trackback || !$c->comment_site) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$posts = dcCore::app()->blog->getPosts(
|
|
||||||
['post_id' => $c->post_id, 'no_content' => true, 'limit' => 1]
|
|
||||||
);
|
);
|
||||||
if ($posts->isEmpty()) {
|
if (!$posts || $posts->isEmpty()) {
|
||||||
return null;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$logs = [
|
$logs = [
|
||||||
$c->comment_author,
|
(string) $cur->getField('comment_author'),
|
||||||
$c->comment_site,
|
(string) $posts->f('post_title'),
|
||||||
$posts->post_title,
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase((string) $posts->f('post_type')) .
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase($posts->post_type) .
|
'/' . $posts->f('post_url') . '#c' . $cur->getField('comment_id'),
|
||||||
'/' . $posts->post_url,
|
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('comment', 'trackback', $logs);
|
ActivityReport::instance()->addLog('comment', 'create', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function categoryCreate($cur, $cat_id)
|
public static function commentUpdate(dcBlog $blog, cursor $cur, dcRecord $old): void
|
||||||
|
{
|
||||||
|
$posts = dcCore::app()->blog?->getPosts(
|
||||||
|
['post_id' => $old->f('post_id'), 'limit' => 1]
|
||||||
|
);
|
||||||
|
if (!$posts || $posts->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$logs = [
|
||||||
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
|
(string) $posts->f('post_title'),
|
||||||
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase((string) $posts->f('post_type')) .
|
||||||
|
'/' . $posts->f('post_url') . '#c' . $old->f('comment_id'),
|
||||||
|
];
|
||||||
|
ActivityReport::instance()->addLog('comment', 'update', $logs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function trackbackCreate(dcBlog $blog, cursor $cur): void
|
||||||
|
{
|
||||||
|
if (!$cur->getField('comment_trackback')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$posts = dcCore::app()->blog?->getPosts(
|
||||||
|
['post_id' => $cur->getField('post_id'), 'no_content' => true, 'limit' => 1]
|
||||||
|
);
|
||||||
|
if (!$posts || $posts->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$logs = [
|
||||||
|
(string) $cur->getField('comment_author'),
|
||||||
|
(string) $cur->getField('comment_site'),
|
||||||
|
(string) $posts->f('post_title'),
|
||||||
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase($posts->f('post_type')) .
|
||||||
|
'/' . $posts->f('post_url'),
|
||||||
|
];
|
||||||
|
ActivityReport::instance()->addLog('comment', 'trackback', $logs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function categoryCreate(cursor $cur, int $cat_id): void
|
||||||
{
|
{
|
||||||
$logs = [
|
$logs = [
|
||||||
$cur->cat_title,
|
(string) $cur->getField('cat_title'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase('category') . '/' . $cur->cat_url,
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase('category') . '/' . $cur->getField('cat_url'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('category', 'create', $logs);
|
ActivityReport::instance()->addLog('category', 'create', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function categoryUpdate($cur, $cat_id)
|
public static function categoryUpdate(cursor $cur, int $cat_id): void
|
||||||
{
|
{
|
||||||
$logs = [
|
$logs = [
|
||||||
$cur->cat_title,
|
(string) $cur->getField('cat_title'),
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase('category') . '/' . $cur->cat_url,
|
(string) dcCore::app()->blog?->url . dcCore::app()->url->getBase('category') . '/' . $cur->getField('cat_url'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('category', 'update', $logs);
|
ActivityReport::instance()->addLog('category', 'update', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function userCreate($cur, $user_id)
|
public static function userCreate(cursor $cur, string $user_id): void
|
||||||
{
|
{
|
||||||
$user_cn = dcUtils::getUserCN(
|
$user_cn = dcUtils::getUserCN(
|
||||||
$cur->user_id,
|
$cur->getField('user_id'),
|
||||||
$cur->user_name,
|
$cur->getField('user_name'),
|
||||||
$cur->user_firstname,
|
$cur->getField('user_firstname'),
|
||||||
$cur->user_displayname
|
$cur->getField('user_displayname')
|
||||||
);
|
);
|
||||||
$logs = [
|
$logs = [
|
||||||
$user_cn,
|
(string) $user_cn,
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('user', 'create', $logs);
|
ActivityReport::instance()->addLog('user', 'create', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function usertUpdate($cur, $user_id)
|
public static function userUpdate(cursor $cur, string $user_id): void
|
||||||
{
|
{
|
||||||
$user_cn = dcUtils::getUserCN(
|
$user_cn = dcUtils::getUserCN(
|
||||||
$cur->user_id,
|
$cur->getField('user_id'),
|
||||||
$cur->user_name,
|
$cur->getField('user_name'),
|
||||||
$cur->user_firstname,
|
$cur->getField('user_firstname'),
|
||||||
$cur->user_displayname
|
$cur->getField('user_displayname')
|
||||||
);
|
);
|
||||||
$logs = [
|
$logs = [
|
||||||
$user_cn,
|
(string) $user_cn,
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('user', 'update', $logs);
|
ActivityReport::instance()->addLog('user', 'update', $logs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function userDelete($user_id)
|
public static function userPreference(cursor $cur, string $user_id): void
|
||||||
|
{
|
||||||
|
$user_cn = dcUtils::getUserCN(
|
||||||
|
$cur->getField('user_id'),
|
||||||
|
$cur->getField('user_name'),
|
||||||
|
$cur->getField('user_firstname'),
|
||||||
|
$cur->getField('user_displayname')
|
||||||
|
);
|
||||||
|
$logs = [
|
||||||
|
(string) $user_cn,
|
||||||
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
|
];
|
||||||
|
ActivityReport::instance()->addLog('user', 'preference', $logs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function userDelete(string $user_id): void
|
||||||
{
|
{
|
||||||
$users = dcCore::app()->getUser($user_id);
|
$users = dcCore::app()->getUser($user_id);
|
||||||
$user_cn = dcUtils::getUserCN(
|
$user_cn = dcUtils::getUserCN(
|
||||||
$users->user_id,
|
$users->f('user_id'),
|
||||||
$users->user_name,
|
$users->f('user_name'),
|
||||||
$users->user_firstname,
|
$users->f('user_firstname'),
|
||||||
$users->user_displayname
|
$users->f('user_displayname')
|
||||||
);
|
);
|
||||||
$logs = [
|
$logs = [
|
||||||
$user_cn,
|
(string) $user_cn,
|
||||||
dcCore::app()->auth->getInfo('user_cn'),
|
(string) dcCore::app()->auth?->getInfo('user_cn'),
|
||||||
];
|
];
|
||||||
dcCore::app()->activityReport->addLog('user', 'delete', $logs);
|
ActivityReport::instance()->addLog('user', 'delete', $logs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
289
src/Backend.php
289
src/Backend.php
@ -10,140 +10,187 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
namespace Dotclear\Plugin\activityReport;
|
||||||
__('Activity report'),
|
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)),
|
|
||||||
dcPage::getPF(basename(__DIR__) . '/icon.png'),
|
|
||||||
preg_match(
|
|
||||||
'/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__))) . '(&.*)?$/',
|
|
||||||
$_SERVER['REQUEST_URI']
|
|
||||||
),
|
|
||||||
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
|
||||||
dcAuth::PERMISSION_ADMIN,
|
|
||||||
]), dcCore::app()->blog->id)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (dcCore::app()->activityReport->getSetting('active')) {
|
use ArrayObject;
|
||||||
dcCore::app()->addBehavior('adminDashboardContentsV2', ['activityReportAdmin', 'adminDashboardContentsV2']);
|
use dcAdmin;
|
||||||
dcCore::app()->addBehavior('adminDashboardOptionsFormV2', ['activityReportAdmin', 'adminDashboardOptionsFormV2']);
|
use dcAuth;
|
||||||
dcCore::app()->addBehavior('adminAfterDashboardOptionsUpdate', ['activityReportAdmin', 'adminAfterDashboardOptionsUpdate']);
|
use dcCore;
|
||||||
}
|
use dcFavorites;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Div,
|
||||||
|
Label,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
|
||||||
class activityReportAdmin
|
/**
|
||||||
|
* Backend process
|
||||||
|
*/
|
||||||
|
class Backend extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function adminDashboardContentsV2($items)
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
dcCore::app()->auth->user_prefs->addWorkspace(basename(__DIR__));
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
$limit = abs((int) dcCore::app()->auth->user_prefs->__get(basename(__DIR__))->dashboard_item);
|
&& defined('ACTIVITY_REPORT')
|
||||||
if (!$limit) {
|
&& My::phpCompliant()
|
||||||
return null;
|
&& My::isInstalled();
|
||||||
}
|
|
||||||
$p = [
|
|
||||||
'limit' => $limit,
|
|
||||||
'order' => 'activity_dt DESC',
|
|
||||||
'sql' => dcCore::app()->activityReport->requests2params(dcCore::app()->activityReport->getSetting('requests')),
|
|
||||||
];
|
|
||||||
$lines = [];
|
|
||||||
$rs = dcCore::app()->activityReport->getLogs($p);
|
|
||||||
if ($rs->isEmpty()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$groups = dcCore::app()->activityReport->getGroups();
|
|
||||||
while ($rs->fetch()) {
|
|
||||||
$group = $rs->activity_group;
|
|
||||||
|
|
||||||
if (!isset($groups[$group])) {
|
return static::$init;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$lines[] = '<dt title="' . __($groups[$group]['title']) . '">' .
|
|
||||||
'<strong>' . __($groups[$group]['actions'][$rs->activity_action]['title']) . '</strong>' .
|
|
||||||
'<br />' . dt::str(
|
|
||||||
dcCore::app()->blog->settings->system->date_format . ', ' . dcCore::app()->blog->settings->system->time_format,
|
|
||||||
strtotime($rs->activity_dt),
|
|
||||||
dcCore::app()->auth->getInfo('user_tz')
|
|
||||||
) . '<dt>' .
|
|
||||||
'<dd><p>' .
|
|
||||||
'<em>' . vsprintf(
|
|
||||||
__($groups[$group]['actions'][$rs->activity_action]['msg']),
|
|
||||||
dcCore::app()->activityReport->decode($rs->activity_logs)
|
|
||||||
) . '</em></p></dd>';
|
|
||||||
}
|
|
||||||
if (empty($lines)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$items[] = new ArrayObject([
|
|
||||||
'<div id="activity-report-logs" class="box medium">' .
|
|
||||||
'<h3>' . __('Activity report') . '</h3>' .
|
|
||||||
'<dl id="reports">' . implode('', $lines) . '</dl>' .
|
|
||||||
'<p class="modules"><a class="module-details" href="' .
|
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__)) . '">' .
|
|
||||||
__('View all logs') . '</a> - <a class="module-config" href="' .
|
|
||||||
dcCore::app()->adminurl->get('admin.plugins', [
|
|
||||||
'module' => basename(__DIR__),
|
|
||||||
'conf' => 1,
|
|
||||||
'redir' => dcCore::app()->adminurl->get('admin.home') . '#activity-report-logs',
|
|
||||||
]) . '">' .
|
|
||||||
__('Configure plugin') . '</a></p>' .
|
|
||||||
'</div>',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function adminDashboardOptionsFormV2()
|
public static function process(): bool
|
||||||
{
|
{
|
||||||
dcCore::app()->auth->user_prefs->addWorkspace(basename(__DIR__));
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
echo
|
|
||||||
'<div class="fieldset">' .
|
|
||||||
'<h4>' . __('Activity report') . '</h4>' .
|
|
||||||
'<p><label for="activityReport_dashboard_item">' .
|
|
||||||
__('Number of activities to show on dashboard:') . '</label>' .
|
|
||||||
form::combo(
|
|
||||||
'activityReport_dashboard_item',
|
|
||||||
self::comboList(),
|
|
||||||
self::comboList(dcCore::app()->auth->user_prefs->__get(basename(__DIR__))->dashboard_item)
|
|
||||||
) . '</p>' .
|
|
||||||
'</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function adminAfterDashboardOptionsUpdate($user_id = null)
|
|
||||||
{
|
|
||||||
if (is_null($user_id)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dcCore::app()->auth->user_prefs->addWorkspace(basename(__DIR__));
|
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||||
dcCore::app()->auth->user_prefs->__get(basename(__DIR__))->put(
|
My::name(),
|
||||||
'dashboard_item',
|
dcCore::app()->adminurl?->get('admin.plugin.' . My::id()),
|
||||||
self::comboList(@$_POST['activityReport_dashboard_item']),
|
dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
'integer'
|
preg_match(
|
||||||
|
'/' . preg_quote((string) dcCore::app()->adminurl?->get('admin.plugin.' . My::id())) . '(&.*)?$/',
|
||||||
|
$_SERVER['REQUEST_URI']
|
||||||
|
),
|
||||||
|
dcCore::app()->auth?->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcAuth::PERMISSION_ADMIN,
|
||||||
|
]), dcCore::app()->blog?->id)
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
private static function comboList($q = true)
|
dcCore::app()->addBehaviors([
|
||||||
{
|
// dashboard favorites icon
|
||||||
$l = [
|
'adminDashboardFavoritesV2' => function (dcFavorites $favs): void {
|
||||||
__('Do not show activity report') => 0,
|
$favs->register(My::id(), [
|
||||||
5 => 5,
|
'title' => My::name(),
|
||||||
10 => 10,
|
'url' => dcCore::app()->adminurl?->get('admin.plugin.' . My::id()),
|
||||||
15 => 15,
|
'small-icon' => dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
20 => 20,
|
'large-icon' => dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
50 => 50,
|
'permissions' => dcCore::app()->auth?->makePermissions([
|
||||||
100 => 100,
|
dcAuth::PERMISSION_ADMIN,
|
||||||
];
|
]),
|
||||||
if (true === $q) {
|
]);
|
||||||
return $l;
|
},
|
||||||
}
|
// dashboard content display
|
||||||
if (!$q) {
|
'adminDashboardContentsV2' => function (ArrayObject $items): void {
|
||||||
$q = -1;
|
$limit = abs((int) dcCore::app()->auth?->user_prefs?->get(My::id())->get('dashboard_item'));
|
||||||
}
|
if (!$limit) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
return in_array($q, $l) ? $l[$q] : 0;
|
$params = new ArrayObject([
|
||||||
|
'limit' => $limit,
|
||||||
|
'requests' => true,
|
||||||
|
]);
|
||||||
|
$rs = ActivityReport::instance()->getLogs($params);
|
||||||
|
if (!$rs || $rs->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$lines = [];
|
||||||
|
$groups = ActivityReport::instance()->groups;
|
||||||
|
while ($rs->fetch()) {
|
||||||
|
if (!$groups->has($rs->f('activity_group'))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$group = $groups->get($rs->f('activity_group'));
|
||||||
|
$lines[] = '<dt title="' . __($group->title) . '">' .
|
||||||
|
'<strong>' . __($group->get($rs->f('activity_action'))->title) . '</strong>' .
|
||||||
|
'<br />' . Date::str(
|
||||||
|
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'),
|
||||||
|
(int) strtotime($rs->f('activity_dt')),
|
||||||
|
dcCore::app()->auth?->getInfo('user_tz')
|
||||||
|
) . '<dt>' .
|
||||||
|
'<dd><p>' .
|
||||||
|
'<em>' . vsprintf(
|
||||||
|
__($group->get($rs->f('activity_action'))->message),
|
||||||
|
json_decode($rs->f('activity_logs'), true)
|
||||||
|
) . '</em></p></dd>';
|
||||||
|
}
|
||||||
|
if (empty($lines)) {
|
||||||
|
return ;
|
||||||
|
}
|
||||||
|
|
||||||
|
$items[] = new ArrayObject([
|
||||||
|
'<div id="activity-report-logs" class="box medium">' .
|
||||||
|
'<h3>' . My::name() . '</h3>' .
|
||||||
|
'<dl id="reports">' . implode('', $lines) . '</dl>' .
|
||||||
|
'<p class="modules"><a class="module-details" href="' .
|
||||||
|
dcCore::app()->adminurl?->get('admin.plugin.' . My::id()) . '">' .
|
||||||
|
__('View all logs') . '</a> - <a class="module-config" href="' .
|
||||||
|
dcCore::app()->adminurl?->get('admin.plugins', [
|
||||||
|
'module' => My::id(),
|
||||||
|
'conf' => 1,
|
||||||
|
'redir' => dcCore::app()->adminurl->get('admin.home'),
|
||||||
|
]) . '">' .
|
||||||
|
__('Configure plugin') . '</a></p>' .
|
||||||
|
'</div>',
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
// dashboard content user preference form
|
||||||
|
'adminDashboardOptionsFormV2' => function (): void {
|
||||||
|
echo
|
||||||
|
(new Div())->class('fieldset')->items([
|
||||||
|
(new Text('h4', My::name())),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Number of activities to show on dashboard:'), Label::OUTSIDE_LABEL_BEFORE))->for(My::id() . '_dashboard_item'),
|
||||||
|
(new Select(My::id() . '_dashboard_item'))->default((string) dcCore::app()->auth?->user_prefs?->get(My::id())->get('dashboard_item'))->items([
|
||||||
|
__('Do not show activity report') => 0,
|
||||||
|
5 => 5,
|
||||||
|
10 => 10,
|
||||||
|
15 => 15,
|
||||||
|
20 => 20,
|
||||||
|
50 => 50,
|
||||||
|
100 => 100,
|
||||||
|
]),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
|
},
|
||||||
|
// save dashboard content user preference
|
||||||
|
'adminAfterDashboardOptionsUpdate' => function (?string $user_id = null): void {
|
||||||
|
if (!is_null($user_id)) {
|
||||||
|
dcCore::app()->auth?->user_prefs?->get(My::id())->put(
|
||||||
|
'dashboard_item',
|
||||||
|
(int) $_POST[My::id() . '_dashboard_item'],
|
||||||
|
'integer'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// list filters
|
||||||
|
'adminFiltersListsV2' => function (ArrayObject $sorts): void {
|
||||||
|
$sorts[My::id()] = [
|
||||||
|
My::name(),
|
||||||
|
[
|
||||||
|
__('Group') => 'activity_group',
|
||||||
|
__('Action') => 'activity_action',
|
||||||
|
__('Date') => 'activity_dt',
|
||||||
|
__('Status') => 'activity_status',
|
||||||
|
],
|
||||||
|
'activity_dt',
|
||||||
|
'desc',
|
||||||
|
[__('logs per page'), 30],
|
||||||
|
];
|
||||||
|
},
|
||||||
|
// list columns user preference
|
||||||
|
'adminColumnsListsV2' => function (ArrayObject $cols): void {
|
||||||
|
$cols[My::id()] = [
|
||||||
|
My::name(),
|
||||||
|
[
|
||||||
|
'activity_group' => [true, __('Group')],
|
||||||
|
'activity_action' => [true, __('Action')],
|
||||||
|
'activity_dt' => [true, __('Date')],
|
||||||
|
'activity_status' => [false, __('Status')],
|
||||||
|
],
|
||||||
|
];
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
72
src/Combo.php
Normal file
72
src/Combo.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Combo helper.
|
||||||
|
*/
|
||||||
|
class Combo
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Mail content formats.
|
||||||
|
*
|
||||||
|
* @return array The formats combo
|
||||||
|
*/
|
||||||
|
public static function mailformat(): array
|
||||||
|
{
|
||||||
|
$combo = [];
|
||||||
|
foreach (ActivityReport::instance()->formats->dump() as $format) {
|
||||||
|
$combo[$format->name] = $format->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $combo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get report intervals.
|
||||||
|
*
|
||||||
|
* @return array The intervals combo
|
||||||
|
*/
|
||||||
|
public static function interval(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('every hour') => 3600,
|
||||||
|
__('every 2 hours') => 7200,
|
||||||
|
__('2 times by day') => 43200,
|
||||||
|
__('every day') => 86400,
|
||||||
|
__('every 2 days') => 172800,
|
||||||
|
__('every week') => 604800,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get obsolete period.
|
||||||
|
*
|
||||||
|
* @return array The obsolete period combo
|
||||||
|
*/
|
||||||
|
public static function obselete(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
__('every hour') => 3600,
|
||||||
|
__('every 2 hours') => 7200,
|
||||||
|
__('2 times by day') => 43200,
|
||||||
|
__('every day') => 86400,
|
||||||
|
__('every 2 days') => 172800,
|
||||||
|
__('every week') => 604800,
|
||||||
|
__('every 2 weeks') => 1209600,
|
||||||
|
__('every 4 weeks') => 2419200,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
412
src/Config.php
412
src/Config.php
@ -10,232 +10,218 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_MODULE')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$super = dcCore::app()->auth->isSuperAdmin() && !empty($_REQUEST['super']);
|
namespace Dotclear\Plugin\activityReport;
|
||||||
$redir = empty($_REQUEST['redir']) ? dcCore::app()->admin->list->getURL() . '#plugins' : $_REQUEST['redir'];
|
|
||||||
|
|
||||||
if ($super) {
|
use dcAuth;
|
||||||
dcCore::app()->activityReport->setGlobal();
|
use dcCore;
|
||||||
}
|
use dcPage;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Checkbox,
|
||||||
|
Div,
|
||||||
|
Hidden,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Note,
|
||||||
|
Para,
|
||||||
|
Select,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
$combo_interval = [
|
/**
|
||||||
__('every hour') => 3600,
|
* Config process.
|
||||||
__('every 2 hours') => 7200,
|
*/
|
||||||
__('2 times by day') => 43200,
|
class Config extends dcNsProcess
|
||||||
__('every day') => 86400,
|
{
|
||||||
__('every 2 days') => 172800,
|
public static function init(): bool
|
||||||
__('every week') => 604800,
|
{
|
||||||
];
|
static::$init == defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& defined('ACTIVITY_REPORT')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& dcCore::app()->auth?->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcAuth::PERMISSION_ADMIN,
|
||||||
|
]), dcCore::app()->blog?->id);
|
||||||
|
|
||||||
$combo_obselete = [
|
return static::$init;
|
||||||
__('every hour') => 3600,
|
}
|
||||||
__('every 2 hours') => 7200,
|
|
||||||
__('2 times by day') => 43200,
|
|
||||||
__('every day') => 86400,
|
|
||||||
__('every 2 days') => 172800,
|
|
||||||
__('every week') => 604800,
|
|
||||||
__('every 2 weeks') => 1209600,
|
|
||||||
__('every 4 weeks') => 2419200,
|
|
||||||
];
|
|
||||||
|
|
||||||
$combo_format = [
|
public static function process(): bool
|
||||||
__('Plain text') => 'plain',
|
{
|
||||||
__('HTML') => 'html',
|
if (!static::$init) {
|
||||||
];
|
return false;
|
||||||
|
|
||||||
if (!empty($_POST['save'])) {
|
|
||||||
try {
|
|
||||||
dcCore::app()->activityReport->setSetting('active', !empty($_POST['active']));
|
|
||||||
if (in_array($_POST['interval'], $combo_interval)) {
|
|
||||||
dcCore::app()->activityReport->setSetting('interval', (int) $_POST['interval']);
|
|
||||||
}
|
}
|
||||||
if (in_array($_POST['obsolete'], $combo_obselete)) {
|
|
||||||
dcCore::app()->activityReport->setSetting('obsolete', (int) $_POST['obsolete']);
|
if (empty($_POST['save'])) {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
dcCore::app()->activityReport->setSetting('mailinglist', explode(';', $_POST['mailinglist']));
|
|
||||||
dcCore::app()->activityReport->setSetting('mailformat', isset($_POST['mailformat']) && $_POST['mailformat'] == 'html' ? 'html' : 'plain');
|
|
||||||
dcCore::app()->activityReport->setSetting('dateformat', html::escapeHTML($_POST['dateformat']));
|
|
||||||
dcCore::app()->activityReport->setSetting('requests', $_POST['requests'] ?? []);
|
|
||||||
dcCore::app()->activityReport->setSetting('blogs', $_POST['blogs'] ?? []);
|
|
||||||
|
|
||||||
if (!empty($_POST['send_report_now'])) {
|
try {
|
||||||
dcCore::app()->activityReport->needReport(true);
|
$s = ActivityReport::instance()->settings;
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
$s->set('feed_active', !empty($_POST['feed_active']));
|
||||||
__('Report successfully sent.')
|
if (in_array($_POST['interval'], Combo::interval())) {
|
||||||
|
$s->set('interval', (int) $_POST['interval']);
|
||||||
|
}
|
||||||
|
if (in_array($_POST['obsolete'], Combo::obselete())) {
|
||||||
|
$s->set('obsolete', (int) $_POST['obsolete']);
|
||||||
|
}
|
||||||
|
$s->set('mailinglist', explode(';', $_POST['mailinglist']));
|
||||||
|
$s->set('mailformat', isset($_POST['mailformat']) && $_POST['mailformat'] == 'html' ? 'html' : 'plain');
|
||||||
|
$s->set('dateformat', $_POST['dateformat']);
|
||||||
|
$s->set('requests', $_POST['requests'] ?? []);
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(
|
||||||
|
__('Configuration successfully updated.')
|
||||||
);
|
);
|
||||||
}
|
|
||||||
if (!empty($_POST['delete_report_now'])) {
|
|
||||||
dcCore::app()->activityReport->deleteLogs();
|
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
if (!empty($_POST['send_report_now'])) {
|
||||||
__('Logs successfully deleted.')
|
ActivityReport::instance()->needReport(true);
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(
|
||||||
|
__('Report successfully sent.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!empty($_POST['delete_report_now'])) {
|
||||||
|
ActivityReport::instance()->deleteLogs();
|
||||||
|
|
||||||
|
dcPage::addSuccessNotice(
|
||||||
|
__('Logs successfully deleted.')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
dcCore::app()->adminurl?->redirect('admin.plugins', [
|
||||||
|
'module' => My::id(),
|
||||||
|
'conf' => 1,
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$s = ActivityReport::instance()->settings;
|
||||||
|
|
||||||
|
if (!$s->lastreport) {
|
||||||
|
$last_report = __('never');
|
||||||
|
$next_report = __('on new activity');
|
||||||
|
} else {
|
||||||
|
$last_report = Date::str(
|
||||||
|
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'),
|
||||||
|
$s->lastreport,
|
||||||
|
dcCore::app()->auth?->getInfo('user_tz')
|
||||||
|
);
|
||||||
|
$next_report = Date::str(
|
||||||
|
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'),
|
||||||
|
$s->interval + $s->lastreport,
|
||||||
|
dcCore::app()->auth?->getInfo('user_tz')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
dcAdminNotices::addSuccessNotice(
|
if (!ActivityReport::hasMailer()) {
|
||||||
__('Configuration successfully updated.')
|
echo '<p class="message">' .
|
||||||
);
|
__('This server has no mail function, activityReport does not send email report.') .
|
||||||
dcCore::app()->adminurl->redirect('admin.plugins', ['module' => basename(__DIR__), 'conf' => 1, 'super' => $super]);
|
'</p>';
|
||||||
} catch (Exception $e) {
|
}
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
|
echo
|
||||||
|
(new Div())->class('two-boxes')->separator('')->items([
|
||||||
|
(new Div())->class('fieldset box odd')->items([
|
||||||
|
(new Text('h4', __('Mail report'))),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Send report:'), Label::OUTSIDE_LABEL_BEFORE))->for('interval'),
|
||||||
|
(new Select('interval'))->default((string) $s->interval)->items(Combo::interval()),
|
||||||
|
]),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Recipients:'), Label::OUTSIDE_LABEL_BEFORE))->for('mailinglist'),
|
||||||
|
(new Input('mailinglist'))->size(60)->maxlenght(255)->value(implode(';', $s->mailinglist)),
|
||||||
|
]),
|
||||||
|
(new Note())->class('form-note')->text(__('Separate multiple email addresses with a semicolon ";"')),
|
||||||
|
(new Note())->class('form-note')->text(__('Leave it empty to disable mail report.')),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Date format:'), Label::OUTSIDE_LABEL_BEFORE))->for('dateformat'),
|
||||||
|
(new Input('dateformat'))->size(60)->maxlenght(255)->value($s->dateformat),
|
||||||
|
]),
|
||||||
|
(new Note())->class('form-note')->text(__('Use Dotclear date formaters. ex: %B %d at %H:%M')),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Report format:'), Label::OUTSIDE_LABEL_BEFORE))->for('mailformat'),
|
||||||
|
(new Select('mailformat'))->default($s->mailformat)->items(Combo::mailformat()),
|
||||||
|
]),
|
||||||
|
(new Text(
|
||||||
|
'ul',
|
||||||
|
'<li>' . __('Last report by email:') . ' ' . $last_report . '</li>' .
|
||||||
|
'<li>' . __('Next report by email:') . ' ' . $next_report . '</li>'
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
(new Div())->class('fieldset box even')->items([
|
||||||
|
(new Text('h4', __('Feeds'))),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Checkbox('feed_active', $s->feed_active))->value(1),
|
||||||
|
(new Label(__('Enable activity feed'), Label::OUTSIDE_LABEL_AFTER))->for('feed_active')->class('classic'),
|
||||||
|
]),
|
||||||
|
(new Text(
|
||||||
|
'ul',
|
||||||
|
'<li><img alt="' . __('RSS feed') . '" src="' . dcPage::getPF(My::id() . '/img/feed.png') . '" /> ' .
|
||||||
|
'<a title="' . __('RSS feed') . '" href="' .
|
||||||
|
dcCore::app()->blog?->url . dcCore::app()->url->getBase(My::id()) . '/rss2/' . ActivityReport::instance()->getUserCode() . '">' .
|
||||||
|
__('Rss2 activities feed') . '</a></li>' .
|
||||||
|
'<li><img alt="' . __('Atom feed') . '" src="' . dcPage::getPF(My::id() . '/img/feed.png') . '" /> ' .
|
||||||
|
'<a title="' . __('Atom feed') . '" href="' .
|
||||||
|
dcCore::app()->blog?->url . dcCore::app()->url->getBase(My::id()) . '/atom/' . ActivityReport::instance()->getUserCode() . '">' .
|
||||||
|
__('Atom activities feed') . '</a></li>'
|
||||||
|
)),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
$g = [
|
||||||
|
(new Text('h4', __('Activities'))),
|
||||||
|
(new Text('p', __('Select actions by activity type to add to report'))),
|
||||||
|
];
|
||||||
|
foreach (ActivityReport::instance()->groups->dump() as $group_id => $group) {
|
||||||
|
$a = [];
|
||||||
|
$a[] = (new Text('h5', __($group->title)));
|
||||||
|
foreach ($group->dump() as $action_id => $action) {
|
||||||
|
$a[] = (new Para())->items([
|
||||||
|
(new Checkbox(
|
||||||
|
['requests[' . $group_id . '][' . $action_id . ']', 'requests_' . $group_id . '_' . $action_id . '_'],
|
||||||
|
isset($s->requests[$group_id][$action_id])
|
||||||
|
))->value(1),
|
||||||
|
(new Label(__($action->title), Label::OUTSIDE_LABEL_AFTER))->for(
|
||||||
|
'requests_' . $group_id . '_' . $action_id . '_'
|
||||||
|
)->class('classic'),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
$g[] = (new Div())->class('fieldset box')->items($a);
|
||||||
|
}
|
||||||
|
echo
|
||||||
|
(new Div('setting_report'))->class('fieldset one-box')->items($g)->render();
|
||||||
|
|
||||||
|
echo
|
||||||
|
(new Div('settings'))->class('fieldset')->items([
|
||||||
|
(new Text('h4', __('Maintenance'))),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Label(__('Automatic cleaning of old logs:'), Label::OUTSIDE_LABEL_BEFORE))->for('obselete'),
|
||||||
|
(new Select('obselete'))->default((string) $s->obsolete)->items(Combo::obselete()),
|
||||||
|
]),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Checkbox('send_report_now'))->value(1),
|
||||||
|
(new Label(__('Send report now'), Label::OUTSIDE_LABEL_AFTER))->for('send_report_now')->class('classic'),
|
||||||
|
]),
|
||||||
|
(new Para())->items([
|
||||||
|
(new Checkbox('delete_report_now'))->value(1),
|
||||||
|
(new Label(__('Delete all logs now'), Label::OUTSIDE_LABEL_AFTER))->for('delete_report_now')->class('classic'),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$last_report_ts = dcCore::app()->activityReport->getSetting('lastreport');
|
|
||||||
if (!$last_report_ts) {
|
|
||||||
$last_report = __('never');
|
|
||||||
$next_report = __('on new activity');
|
|
||||||
} else {
|
|
||||||
$last_report = dt::str(
|
|
||||||
dcCore::app()->blog->settings->system->date_format . ', ' . dcCore::app()->blog->settings->system->time_format,
|
|
||||||
$last_report_ts,
|
|
||||||
dcCore::app()->auth->getInfo('user_tz')
|
|
||||||
);
|
|
||||||
$next_report = dt::str(
|
|
||||||
dcCore::app()->blog->settings->system->date_format . ', ' . dcCore::app()->blog->settings->system->time_format,
|
|
||||||
(int) dcCore::app()->activityReport->getSetting('interval') + $last_report_ts,
|
|
||||||
dcCore::app()->auth->getInfo('user_tz')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
$emails = implode(';', dcCore::app()->activityReport->getSetting('mailinglist'));
|
|
||||||
|
|
||||||
echo '<p class="warn">' . ($super ? __('All blogs') : __('Current blog')) . '</p>';
|
|
||||||
|
|
||||||
if (dcCore::app()->auth->isSuperAdmin()) {
|
|
||||||
echo sprintf(
|
|
||||||
'<p class="modules right"><a class="module-config" href="%s">%s</a><br class="clear"/></p>',
|
|
||||||
dcCore::app()->adminurl->get('admin.plugins', ['module' => basename(__DIR__), 'conf' => 1, 'super' => !$super]),
|
|
||||||
sprintf(__('Configure activity report for %s'), $super ? __('current blog') : __('all blogs'))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!activityReport::hasMailer()) {
|
|
||||||
echo '<p class="message">' .
|
|
||||||
__('This server has no mail function, activityReport does not send email report.') .
|
|
||||||
'</p>';
|
|
||||||
}
|
|
||||||
|
|
||||||
echo '
|
|
||||||
<div class="fieldset two-cols" id="settings"><h4>' . __('Settings') . '</h4>
|
|
||||||
<div class="col">
|
|
||||||
|
|
||||||
<p><label class="classic" for="active">' .
|
|
||||||
form::checkbox('active', '1', dcCore::app()->activityReport->getSetting('active')) . ' ' .
|
|
||||||
(
|
|
||||||
$super ?
|
|
||||||
__('Enable super administrator report') :
|
|
||||||
__('Enable report on this blog')
|
|
||||||
) . '</label></p>
|
|
||||||
|
|
||||||
<p><label for="obselete">' . __('Automatic cleaning of old logs:') . '</label>' .
|
|
||||||
form::combo('obsolete', $combo_obselete, dcCore::app()->activityReport->getSetting('obsolete')) . '</p>
|
|
||||||
|
|
||||||
<p><label for="dateformat">' . __('Date format:') . '<br />' .
|
|
||||||
form::field('dateformat', 60, 255, dcCore::app()->activityReport->getSetting('dateformat')) . '</label></p>
|
|
||||||
<p class="form-note">' . __('Use Dotclear date formaters. ex: %B %d at %H:%M') . '</p>' .
|
|
||||||
|
|
||||||
form::hidden(['super'], $super);
|
|
||||||
|
|
||||||
if (!$super) {
|
|
||||||
echo
|
|
||||||
'<p><img alt="' . __('RSS feed') . '" src="' . dcPage::getPF(basename(__DIR__) . '/inc/img/feed.png') . '" />' .
|
|
||||||
'<a title="' . __('RSS feed') . '" href="' .
|
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase(basename(__DIR__)) . '/rss2/' . dcCore::app()->activityReport->getUserCode() . '">' .
|
|
||||||
__('Rss2 feed for activity on this blog') . '</a><br />' .
|
|
||||||
'<img alt="' . __('Atom feed') . '" src="' . dcPage::getPF(basename(__DIR__) . '/inc/img/feed.png') . '" />' .
|
|
||||||
'<a title="' . __('Atom feed') . '" href="' .
|
|
||||||
dcCore::app()->blog->url . dcCore::app()->url->getBase(basename(__DIR__)) . '/atom/' . dcCore::app()->activityReport->getUserCode() . '">' .
|
|
||||||
__('Atom feed for activity on this blog') . '</a></p>';
|
|
||||||
}
|
|
||||||
echo '
|
|
||||||
</div><div class="col">
|
|
||||||
|
|
||||||
<p><label for="interval">' . __('Send report:') . '</label>' .
|
|
||||||
form::combo('interval', $combo_interval, dcCore::app()->activityReport->getSetting('interval')) . '</p>
|
|
||||||
|
|
||||||
<p><label for="mailinglist">' . __('Recipients:') . '<br />' .
|
|
||||||
form::field('mailinglist', 60, 255, $emails) . '</label></p>
|
|
||||||
<p class="form-note">' . __('Separate multiple email addresses with a semicolon ";"') . '</p>
|
|
||||||
|
|
||||||
<p><label for="mailformat">' . __('Report format:') . '</label>' .
|
|
||||||
form::combo('mailformat', $combo_format, dcCore::app()->activityReport->getSetting('mailformat')) . '</p>
|
|
||||||
|
|
||||||
<ul>
|
|
||||||
<li>' . __('Last report by email:') . ' ' . $last_report . '</li>
|
|
||||||
<li>' . __('Next report by email:') . ' ' . $next_report . '</li>
|
|
||||||
</ul>
|
|
||||||
</div><br class="clear"/>
|
|
||||||
</div><br class="clear"/>';
|
|
||||||
|
|
||||||
if ($super) {
|
|
||||||
echo '
|
|
||||||
<div class="fieldset one-box" id="setting_blog"><h4>' . __('Blogs') . '</h4>
|
|
||||||
<p>' . __('Select blogs to add to report') . '</p>';
|
|
||||||
|
|
||||||
$i = $j = 0;
|
|
||||||
$selected_blogs = dcCore::app()->activityReport->getSetting('blogs');
|
|
||||||
$blogs = dcCore::app()->getBlogs();
|
|
||||||
$num_blogs = $blogs->count();
|
|
||||||
while ($blogs->fetch()) {
|
|
||||||
$blog_id = dcCore::app()->con->escape($blogs->blog_id);
|
|
||||||
|
|
||||||
echo '
|
|
||||||
<div class="fieldset box">
|
|
||||||
<p><label class="classic" for="blogs_' . $i . '_">' .
|
|
||||||
form::checkbox(
|
|
||||||
['blogs[' . $i . ']', 'blogs_' . $i . '_'],
|
|
||||||
$blog_id,
|
|
||||||
in_array($blog_id, $selected_blogs)
|
|
||||||
) . ' ' .
|
|
||||||
$blogs->blog_name . ' (' . $blog_id . ')</label></p>
|
|
||||||
</div>';
|
|
||||||
|
|
||||||
$i++;
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
} else {
|
|
||||||
echo form::hidden('blogs[0]', dcCore::app()->blog->id);
|
|
||||||
}
|
|
||||||
echo '
|
|
||||||
<div class="fieldset one-box" id="setting_report"><h4>' . __('Report') . '</h4>
|
|
||||||
<p>' . __('Select actions by activity type to add to report') . '</p>';
|
|
||||||
|
|
||||||
$groups = dcCore::app()->activityReport->getGroups();
|
|
||||||
$blog_request = dcCore::app()->activityReport->getSetting('requests');
|
|
||||||
|
|
||||||
$i = 0;
|
|
||||||
foreach ($groups as $group_id => $group) {
|
|
||||||
echo '<div class="fieldset box"><h5>' . __($group['title']) . '</h5>';
|
|
||||||
|
|
||||||
foreach ($group['actions'] as $action_id => $action) {
|
|
||||||
echo '
|
|
||||||
<p><label class="classic" for="requests_' . $group_id . '_' . $action_id . '_">' .
|
|
||||||
form::checkbox(
|
|
||||||
['requests[' . $group_id . '][' . $action_id . ']', 'requests_' . $group_id . '_' . $action_id . '_'],
|
|
||||||
1,
|
|
||||||
isset($blog_request[$group_id][$action_id])
|
|
||||||
) . ' ' . __($action['title']) . '</label></p>';
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
}
|
|
||||||
echo '</div>';
|
|
||||||
|
|
||||||
if (1) {
|
|
||||||
echo '
|
|
||||||
<div class="fieldset" id="settings"><h4>' . __('Special') . '</h4>
|
|
||||||
|
|
||||||
<p><label class="classic" for="send_report_now">' .
|
|
||||||
form::checkbox('send_report_now', '1', false) . ' ' .
|
|
||||||
__('Send report now') . '</label></p>
|
|
||||||
|
|
||||||
<p><label class="classic" for="delete_report_now">' .
|
|
||||||
form::checkbox('delete_report_now', '1', false) . ' ' .
|
|
||||||
__('Delete all logs now') . '</label></p>
|
|
||||||
|
|
||||||
</div>';
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->activityReport->unsetGlobal();
|
|
||||||
|
71
src/Context.php
Normal file
71
src/Context.php
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template helper.
|
||||||
|
*/
|
||||||
|
class Context
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Parse title.
|
||||||
|
*
|
||||||
|
* @return string The parsed title
|
||||||
|
*/
|
||||||
|
public static function parseTitle(): string
|
||||||
|
{
|
||||||
|
if (!dcCore::app()->ctx || !dcCore::app()->ctx->exists('activityreports')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$group = dcCore::app()->ctx->__get('activityreports')->activity_group;
|
||||||
|
$action = dcCore::app()->ctx->__get('activityreports')->activity_action;
|
||||||
|
|
||||||
|
if (!ActivityReport::instance()->groups->get($group)->has($action)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return __(ActivityReport::instance()->groups->get($group)->get($action)->title);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse content.
|
||||||
|
*
|
||||||
|
* @return string The parsed content
|
||||||
|
*/
|
||||||
|
public static function parseContent(): string
|
||||||
|
{
|
||||||
|
if (!dcCore::app()->ctx || !dcCore::app()->ctx->exists('activityreports')) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$group = dcCore::app()->ctx->__get('activityreports')->activity_group;
|
||||||
|
$action = dcCore::app()->ctx->__get('activityreports')->activity_action;
|
||||||
|
$logs = json_decode((string) dcCore::app()->ctx->__get('activityreports')->activity_logs, true);
|
||||||
|
|
||||||
|
if (!is_array($logs) || !ActivityReport::instance()->groups->get($group)->has($action)) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
dcCore::app()->initWikiComment();
|
||||||
|
|
||||||
|
return dcCore::app()->wikiTransform(vsprintf(
|
||||||
|
__(ActivityReport::instance()->groups->get($group)->get($action)->message),
|
||||||
|
$logs
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
81
src/Format.php
Normal file
81
src/Format.php
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report format descriptor.
|
||||||
|
*/
|
||||||
|
class Format
|
||||||
|
{
|
||||||
|
/** @var string $name The name format */
|
||||||
|
public readonly string $name;
|
||||||
|
|
||||||
|
/** @var string $blog_title The blog title format */
|
||||||
|
public readonly string $blog_title;
|
||||||
|
|
||||||
|
/** @var string $group_title The group title format */
|
||||||
|
public readonly string $group_title;
|
||||||
|
|
||||||
|
/** @var string $group_open The group opening format */
|
||||||
|
public readonly string $group_open;
|
||||||
|
|
||||||
|
/** @var string $group_close The group closing format */
|
||||||
|
public readonly string $group_close;
|
||||||
|
|
||||||
|
/** @var string $action The action format */
|
||||||
|
public readonly string $action;
|
||||||
|
|
||||||
|
/** @var string $error The error format */
|
||||||
|
public readonly string $error;
|
||||||
|
|
||||||
|
/** @var string $period_title The period title format */
|
||||||
|
public readonly string $period_title;
|
||||||
|
|
||||||
|
/** @var string $period_open The period opening format */
|
||||||
|
public readonly string $period_open;
|
||||||
|
|
||||||
|
/** @var string $period_close The period closing format */
|
||||||
|
public readonly string $period_close;
|
||||||
|
|
||||||
|
/** @var string $info The info format */
|
||||||
|
public readonly string $info;
|
||||||
|
|
||||||
|
/** @var string $page The page format */
|
||||||
|
public readonly string $page;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor sets format id.
|
||||||
|
*
|
||||||
|
* @param string $id The format ID
|
||||||
|
* @param array $format The format values
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
public readonly string $id,
|
||||||
|
array $format
|
||||||
|
) {
|
||||||
|
$this->name = $format['name'] ?? __('Plain text');
|
||||||
|
$this->blog_title = $format['blog_title'] ?? "\n--- %TEXT% ---\n";
|
||||||
|
$this->group_title = $format['group_title'] ?? "\n-- %TEXT% --\n\n";
|
||||||
|
$this->group_open = $format['group_open'] ?? '';
|
||||||
|
$this->group_close = $format['group_close'] ?? '';
|
||||||
|
$this->action = $format['action'] ?? "- %TIME% : %TEXT%\n";
|
||||||
|
$this->error = $format['error'] ?? '%TEXT%';
|
||||||
|
$this->period_title = $format['period_title'] ?? "%TEXT%\n";
|
||||||
|
$this->period_open = $format['period_open'] ?? '';
|
||||||
|
$this->period_close = $format['period_close'] ?? '';
|
||||||
|
$this->info = $format['info'] ?? "%TEXT%\n";
|
||||||
|
$this->page = $format['page'] ?? "%PERIOD%\n-----------------------------------------------------------\n%TEXT%";
|
||||||
|
}
|
||||||
|
}
|
109
src/Formats.php
109
src/Formats.php
@ -10,52 +10,63 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
$format = [
|
declare(strict_types=1);
|
||||||
'html' => [
|
|
||||||
'blog_title' => '<h2><a href="%URL%">%TEXT%</a></h2>',
|
namespace Dotclear\Plugin\activityReport;
|
||||||
'blog_open' => '',
|
|
||||||
'blog_close' => '',
|
/**
|
||||||
'group_title' => '<h3>%TEXT%</h3>',
|
* Email report formats stack.
|
||||||
'group_open' => '<ul>',
|
*/
|
||||||
'group_close' => '</ul>',
|
class Formats
|
||||||
'action' => '<li><em>%TIME%</em><br />%TEXT%</li>',
|
{
|
||||||
'error' => '<p>%TEXT%</p>',
|
/** @var array<string, Format> $stack The formats stack */
|
||||||
'period_title' => '<h1>%TEXT%</h1>',
|
private array $stack = [];
|
||||||
'period_open' => '<ul>',
|
|
||||||
'period_close' => '</ul>',
|
/**
|
||||||
'info' => '<li>%TEXT%</li>',
|
* Chek if a format exists.
|
||||||
'page' => '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n" .
|
*
|
||||||
'<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' . "\n" .
|
* @param string $id The format ID
|
||||||
'<head><title>' . __('Activity report') . '</title>' .
|
*
|
||||||
'<style type="text/css">' .
|
* @return bool True if it exists
|
||||||
' body { color: #303030; background: #FCFCFC; font-size: 0.7em;font-family: Georgia, Tahoma, Arial, Helvetica, sans-serif; }' .
|
*/
|
||||||
' a { color: #303030; text-decoration: none; }' .
|
public function has(string $id): bool
|
||||||
' h1 { text-align: center; font-size: 2em; }' .
|
{
|
||||||
' h2 { color: #303030; text-align:center; }' .
|
return isset($this->stack[$id]);
|
||||||
' h3 { color: #7F3F3F; }' .
|
}
|
||||||
' li em { color: #303030; }' .
|
|
||||||
' div.info { color: #3F497F; background-color: #F8F8EB; border: 1px solid #888888; margin: 4px; padding: 4px; }' .
|
/**
|
||||||
' div.content { color: #3F7F47; background-color: #F8F8EB; border: 1px solid #888888; margin: 4px; padding: 4px; }' .
|
* Add a format.
|
||||||
' div.foot { text-align:center; font-size: 0.9em; }' .
|
*
|
||||||
'</style>' .
|
* @param Format $format The format object
|
||||||
'</head><body>' .
|
*
|
||||||
'<div class="info">%PERIOD%</div><div class="content">%TEXT%</div>' .
|
* @return Formats The formats instance
|
||||||
'<div class="foot"><p>Powered by <a href="https://github.com/JcDenis/activityReport">activityReport</a></p></div>' .
|
*/
|
||||||
'</body></html>',
|
public function add(Format $format): Formats
|
||||||
],
|
{
|
||||||
'plain' => [
|
$this->stack[$format->id] = $format;
|
||||||
'blog_title' => "\n--- %TEXT% ---\n",
|
|
||||||
'blog_open' => '',
|
return $this;
|
||||||
'blog_close' => '',
|
}
|
||||||
'group_title' => "\n-- %TEXT% --\n\n",
|
|
||||||
'group_open' => '',
|
/**
|
||||||
'group_close' => '',
|
* Get a format.
|
||||||
'action' => "- %TIME% : %TEXT%\n",
|
*
|
||||||
'error' => '%TEXT%',
|
* @param string $id The format ID
|
||||||
'period_title' => "%TEXT%\n",
|
*
|
||||||
'period_open' => '',
|
* @return Format The format descriptor
|
||||||
'period_close' => '',
|
*/
|
||||||
'info' => "%TEXT%\n",
|
public function get(string $id): Format
|
||||||
'page' => "%PERIOD%\n-----------------------------------------------------------\n%TEXT%",
|
{
|
||||||
],
|
return $this->stack[$id] ?? new Format('plain', []);
|
||||||
];
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all formats.
|
||||||
|
*
|
||||||
|
* @return array<string, Format> The formats stack
|
||||||
|
*/
|
||||||
|
public function dump(): array
|
||||||
|
{
|
||||||
|
return $this->stack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
178
src/Frontend.php
178
src/Frontend.php
@ -10,165 +10,41 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), __DIR__ . '/default-templates/tpl');
|
namespace Dotclear\Plugin\activityReport;
|
||||||
dcCore::app()->tpl->addBlock('activityReports', ['activityReportPublicTpl','activityReports']);
|
|
||||||
dcCore::app()->tpl->addValue('activityReportFeedID', ['activityReportPublicTpl','activityReportFeedID']);
|
|
||||||
dcCore::app()->tpl->addValue('activityReportTitle', ['activityReportPublicTpl','activityReportTitle']);
|
|
||||||
dcCore::app()->tpl->addValue('activityReportDate', ['activityReportPublicTpl','activityReportDate']);
|
|
||||||
dcCore::app()->tpl->addValue('activityReportContent', ['activityReportPublicTpl','activityReportContent']);
|
|
||||||
|
|
||||||
class activityReportPublicUrl extends dcUrlHandlers
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Front end process.
|
||||||
|
*/
|
||||||
|
class Frontend extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function feed(?string $args): void
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
if (!preg_match('/^(atom|rss2)\/(.+)$/', $args, $m)) {
|
static::$init = defined('ACTIVITY_REPORT')
|
||||||
self::p404();
|
&& My::phpCompliant()
|
||||||
|
&& My::isInstalled();
|
||||||
|
|
||||||
return;
|
return static::$init;
|
||||||
}
|
}
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
|
||||||
self::p404();
|
|
||||||
|
|
||||||
return;
|
public static function process(): bool
|
||||||
}
|
{
|
||||||
if (!dcCore::app()->activityReport->getSetting('active')) {
|
if (!static::$init) {
|
||||||
self::p404();
|
return false;
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$mime = $m[1] == 'atom' ? 'application/atom+xml' : 'application/xml';
|
|
||||||
|
|
||||||
if (false === dcCore::app()->activityReport->checkUserCode($m[2])) {
|
|
||||||
self::p404();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dcCore::app()->ctx->nb_entry_per_page = (int) dcCore::app()->blog->settings->system->nb_post_per_feed;
|
dcCore::app()->tpl->setPath(dcCore::app()->tpl->getPath(), implode(DIRECTORY_SEPARATOR, [My::root(), 'default-templates', 'tpl']));
|
||||||
dcCore::app()->ctx->short_feed_items = (int) dcCore::app()->blog->settings->system->short_feed_items;
|
|
||||||
|
|
||||||
header('X-Robots-Tag: ' . context::robotsPolicy(dcCore::app()->blog->settings->system->robots_policy, ''));
|
dcCore::app()->tpl->addBlock('activityReports', [Template::class, 'activityReports']);
|
||||||
self::serveDocument('activityreport-' . $m[1] . '.xml', $mime);
|
dcCore::app()->tpl->addValue('activityReportFeedID', [Template::class, 'activityReportFeedID']);
|
||||||
}
|
dcCore::app()->tpl->addValue('activityReportTitle', [Template::class, 'activityReportTitle']);
|
||||||
}
|
dcCore::app()->tpl->addValue('activityReportDate', [Template::class, 'activityReportDate']);
|
||||||
|
dcCore::app()->tpl->addValue('activityReportContent', [Template::class, 'activityReportContent']);
|
||||||
class activityReportPublicTpl
|
|
||||||
{
|
return true;
|
||||||
public static function activityReports($attr, $content)
|
|
||||||
{
|
|
||||||
$lastn = 0;
|
|
||||||
if (isset($attr['lastn'])) {
|
|
||||||
$lastn = abs((int) $attr['lastn']) + 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$p = '$_page_number = dcCore::app()->public->getPageNumber(); if ($_page_number < 1) { $_page_number = 1; }' . "\n\$params = array();\n";
|
|
||||||
|
|
||||||
if ($lastn > 0) {
|
|
||||||
$p .= "\$params['limit'] = " . $lastn . ";\n";
|
|
||||||
} else {
|
|
||||||
$p .= "\$params['limit'] = dcCore::app()->ctx->nb_entry_per_page;\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == '0') {
|
|
||||||
$p .= "\$params['limit'] = array(((\$_page_number-1)*\$params['limit']),\$params['limit']);\n";
|
|
||||||
} else {
|
|
||||||
$p .= "\$params['limit'] = array(0, \$params['limit']);\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
"<?php \n" .
|
|
||||||
$p .
|
|
||||||
'dcCore::app()->ctx->activityreport_params = $params; ' . "\n" .
|
|
||||||
'dcCore::app()->ctx->activityreports = dcCore::app()->activityReport->getLogs($params); unset($params); ' . "\n" .
|
|
||||||
'while (dcCore::app()->ctx->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' .
|
|
||||||
'dcCore::app()->ctx->pop("activityreports"); dcCore::app()->ctx->pop("activityreport_params"); ' . "\n" .
|
|
||||||
'?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function activityReportFeedID($attr)
|
|
||||||
{
|
|
||||||
return
|
|
||||||
'urn:md5:<?php echo md5(dcCore::app()->ctx->activityreports->blog_id.' .
|
|
||||||
'dcCore::app()->ctx->activityreports->activity_id.dcCore::app()->ctx->activityreports->activity_dt); ' .
|
|
||||||
'?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function activityReportTitle($attr)
|
|
||||||
{
|
|
||||||
$f = dcCore::app()->tpl->getFilters($attr);
|
|
||||||
|
|
||||||
return '<?php echo ' . sprintf($f, 'activityReportContext::parseTitle()') . '; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function activityReportContent($attr)
|
|
||||||
{
|
|
||||||
$f = dcCore::app()->tpl->getFilters($attr);
|
|
||||||
|
|
||||||
return '<?php echo ' . sprintf($f, 'activityReportContext::parseContent()') . '; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function activityReportDate($attr)
|
|
||||||
{
|
|
||||||
$format = '';
|
|
||||||
if (!empty($attr['format'])) {
|
|
||||||
$format = addslashes($attr['format']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$iso8601 = !empty($attr['iso8601']);
|
|
||||||
$rfc822 = !empty($attr['rfc822']);
|
|
||||||
|
|
||||||
$f = dcCore::app()->tpl->getFilters($attr);
|
|
||||||
|
|
||||||
if ($rfc822) {
|
|
||||||
return '<?php echo ' . sprintf($f, 'dt::rfc822(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>';
|
|
||||||
} elseif ($iso8601) {
|
|
||||||
return '<?php echo ' . sprintf($f, 'dt::iso8601(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>';
|
|
||||||
} elseif (!empty($format)) {
|
|
||||||
return '<?php echo ' . sprintf($f, "dt::dt2str('" . $format . "',dcCore::app()->ctx->activityreports->activity_dt)") . '; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '<?php echo ' . sprintf($f, 'dt::dt2str(dcCore::app()->blog->settings->system->date_format,dcCore::app()->ctx->activityreports->activity_dt)') . '; ?>';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class activityReportContext
|
|
||||||
{
|
|
||||||
public static function parseTitle()
|
|
||||||
{
|
|
||||||
$groups = dcCore::app()->activityReport->getGroups();
|
|
||||||
|
|
||||||
$group = dcCore::app()->ctx->activityreports->activity_group;
|
|
||||||
$action = dcCore::app()->ctx->activityreports->activity_action;
|
|
||||||
|
|
||||||
if (!empty($groups[$group]['actions'][$action]['title'])) {
|
|
||||||
return __($groups[$group]['actions'][$action]['title']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function parseContent()
|
|
||||||
{
|
|
||||||
$groups = dcCore::app()->activityReport->getGroups();
|
|
||||||
|
|
||||||
$group = dcCore::app()->ctx->activityreports->activity_group;
|
|
||||||
$action = dcCore::app()->ctx->activityreports->activity_action;
|
|
||||||
$logs = dcCore::app()->ctx->activityreports->activity_logs;
|
|
||||||
$logs = dcCore::app()->activityReport->decode($logs);
|
|
||||||
|
|
||||||
if (!empty($groups[$group]['actions'][$action]['msg'])) {
|
|
||||||
dcCore::app()->initWikiComment();
|
|
||||||
|
|
||||||
return dcCore::app()->wikiTransform(vsprintf(__($groups[$group]['actions'][$action]['msg']), $logs));
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
82
src/Group.php
Normal file
82
src/Group.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions stack.
|
||||||
|
*/
|
||||||
|
class Group
|
||||||
|
{
|
||||||
|
/** @var array<string, Action> $stack The actions stack */
|
||||||
|
private array $stack = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor sets group description.
|
||||||
|
*
|
||||||
|
* @param string $id The group ID
|
||||||
|
* @param string $title The group title
|
||||||
|
*/
|
||||||
|
public function __construct(public readonly string $id, public readonly string $title)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chek if a action exists.
|
||||||
|
*
|
||||||
|
* @param string $id The action ID
|
||||||
|
*
|
||||||
|
* @return bool True if it exists
|
||||||
|
*/
|
||||||
|
public function has(string $id): bool
|
||||||
|
{
|
||||||
|
return isset($this->stack[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an action.
|
||||||
|
*
|
||||||
|
* @param Action $action The action object
|
||||||
|
*
|
||||||
|
* @return Group The group instance
|
||||||
|
*/
|
||||||
|
public function add(Action $action): Group
|
||||||
|
{
|
||||||
|
$this->stack[$action->id] = $action;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an action.
|
||||||
|
*
|
||||||
|
* @param string $id The action ID
|
||||||
|
*
|
||||||
|
* @return Action The action descriptor
|
||||||
|
*/
|
||||||
|
public function get(string $id): Action
|
||||||
|
{
|
||||||
|
return $this->stack[$id] ?? new Action($id, 'undefined', 'undefined', 'undefined', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all actions.
|
||||||
|
*
|
||||||
|
* @return array<string, Action> The actions stack
|
||||||
|
*/
|
||||||
|
public function dump(): array
|
||||||
|
{
|
||||||
|
return $this->stack;
|
||||||
|
}
|
||||||
|
}
|
72
src/Groups.php
Normal file
72
src/Groups.php
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Actions groups stack.
|
||||||
|
*/
|
||||||
|
class Groups
|
||||||
|
{
|
||||||
|
/** @var array<string, Group> $stack The actions groups stack */
|
||||||
|
private array $stack = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chek if a group exists.
|
||||||
|
*
|
||||||
|
* @param string $id The group ID
|
||||||
|
*
|
||||||
|
* @return bool True if it exists
|
||||||
|
*/
|
||||||
|
public function has(string $id): bool
|
||||||
|
{
|
||||||
|
return isset($this->stack[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a group.
|
||||||
|
*
|
||||||
|
* @param Group $group The group object
|
||||||
|
*
|
||||||
|
* @return Groups The groups instance
|
||||||
|
*/
|
||||||
|
public function add(Group $group): Groups
|
||||||
|
{
|
||||||
|
$this->stack[$group->id] = $group;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a group.
|
||||||
|
*
|
||||||
|
* @param string $id The group ID
|
||||||
|
*
|
||||||
|
* @return Group The group descriptor
|
||||||
|
*/
|
||||||
|
public function get(string $id): Group
|
||||||
|
{
|
||||||
|
return $this->stack[$id] ?? new Group($id, 'undefined');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all groups.
|
||||||
|
*
|
||||||
|
* @return array<string, Group> The groups stack
|
||||||
|
*/
|
||||||
|
public function dump(): array
|
||||||
|
{
|
||||||
|
return $this->stack;
|
||||||
|
}
|
||||||
|
}
|
132
src/Install.php
132
src/Install.php
@ -10,53 +10,87 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dbStruct;
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Database\Statement\{
|
||||||
|
DropStatement,
|
||||||
|
TruncateStatement
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Install process.
|
||||||
|
*/
|
||||||
|
class Install extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version'));
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
self::beforeGrowUp();
|
||||||
|
|
||||||
|
$s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
||||||
|
$s->{My::ACTIVITY_TABLE_NAME}
|
||||||
|
->activity_id('bigint', 0, false)
|
||||||
|
->activity_type('varchar', 32, false, "'" . My::id() . "'")
|
||||||
|
->blog_id('varchar', 32, true)
|
||||||
|
->activity_group('varchar', 32, false)
|
||||||
|
->activity_action('varchar', 32, false)
|
||||||
|
->activity_logs('text', 0, false)
|
||||||
|
->activity_dt('timestamp', 0, false, 'now()')
|
||||||
|
->activity_status('smallint', 0, false, 0)
|
||||||
|
|
||||||
|
->primary('pk_activity', 'activity_id')
|
||||||
|
->index('idx_activity_type', 'btree', 'activity_type')
|
||||||
|
->index('idx_activity_blog_id', 'btree', 'blog_id')
|
||||||
|
->index('idx_activity_action', 'btree', 'activity_group', 'activity_action')
|
||||||
|
->index('idx_activity_status', 'btree', 'activity_status');
|
||||||
|
|
||||||
|
(new dbStruct(dcCore::app()->con, dcCore::app()->prefix))->synchronize($s);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do some action on previous version before install.
|
||||||
|
*/
|
||||||
|
private static function beforeGrowUp(): void
|
||||||
|
{
|
||||||
|
$current = dcCore::app()->getVersion('activityReport');
|
||||||
|
|
||||||
|
// sorry not sorry we restart from scratch
|
||||||
|
if ($current && version_compare($current, '3.0', '<')) {
|
||||||
|
$struct = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
||||||
|
|
||||||
|
if ($struct->tableExists('activity')) {
|
||||||
|
(new TruncateStatement())->from(dcCore::app()->prefix . 'activity')->truncate();
|
||||||
|
}
|
||||||
|
if ($struct->tableExists('activity_settings')) {
|
||||||
|
(new TruncateStatement())->from(dcCore::app()->prefix . 'activity_settings')->truncate();
|
||||||
|
(new DropStatement())->from(dcCore::app()->prefix . 'activity_settings')->drop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dcCore::app()->newVersion(
|
|
||||||
basename(__DIR__),
|
|
||||||
dcCore::app()->plugins->moduleInfo(basename(__DIR__), 'version')
|
|
||||||
)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$s = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
|
||||||
$s->{initActivityReport::ACTIVITY_TABLE_NAME}
|
|
||||||
->activity_id('bigint', 0, false)
|
|
||||||
->activity_type('varchar', 32, false, "'" . basename(__DIR__) . "'")
|
|
||||||
->blog_id('varchar', 32, true)
|
|
||||||
->activity_group('varchar', 32, false)
|
|
||||||
->activity_action('varchar', 32, false)
|
|
||||||
->activity_logs('text', 0, false)
|
|
||||||
->activity_dt('timestamp', 0, false, 'now()')
|
|
||||||
->activity_blog_status('smallint', 0, false, 0)
|
|
||||||
->activity_super_status('smallint', 0, false, 0)
|
|
||||||
|
|
||||||
->primary('pk_activity', 'activity_id')
|
|
||||||
->index('idx_activity_type', 'btree', 'activity_type')
|
|
||||||
->index('idx_activity_blog_id', 'btree', 'blog_id')
|
|
||||||
->index('idx_activity_action', 'btree', 'activity_group', 'activity_action')
|
|
||||||
->index('idx_activity_blog_status', 'btree', 'activity_blog_status')
|
|
||||||
->index('idx_activity_super_status', 'btree', 'activity_super_status');
|
|
||||||
|
|
||||||
$s->{initActivityReport::SETTING_TABLE_NAME}
|
|
||||||
->setting_id('varchar', 64, false)
|
|
||||||
->blog_id('varchar', 32, true)
|
|
||||||
->setting_type('varchar', 32, false)
|
|
||||||
->setting_value('text', 0, false)
|
|
||||||
|
|
||||||
->unique('uk_activity_setting', 'setting_id', 'blog_id', 'setting_type')
|
|
||||||
->index('idx_activity_setting_blog_id', 'btree', 'blog_id')
|
|
||||||
->index('idx_activity_setting_type', 'btree', 'setting_type');
|
|
||||||
|
|
||||||
$si = new dbStruct(dcCore::app()->con, dcCore::app()->prefix);
|
|
||||||
$changes = $si->synchronize($s);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
} catch (Exception $e) {
|
|
||||||
dcCore::app()->error->add($e->getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
|
167
src/Manage.php
167
src/Manage.php
@ -10,83 +10,114 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
namespace Dotclear\Plugin\activityReport;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
dcPage::check(dcCore::app()->auth->makePermissions([
|
use ArrayObject;
|
||||||
dcAuth::PERMISSION_ADMIN,
|
use adminGenericFilter;
|
||||||
]));
|
use dcAuth;
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use dcPage;
|
||||||
|
use Dotclear\Helper\Html\Form\{
|
||||||
|
Form,
|
||||||
|
Hidden,
|
||||||
|
Para,
|
||||||
|
Submit,
|
||||||
|
Text
|
||||||
|
};
|
||||||
|
use Exception;
|
||||||
|
|
||||||
$super = dcCore::app()->auth->isSuperAdmin() && !empty($_REQUEST['super']);
|
/**
|
||||||
|
* Manage process (admin logs list).
|
||||||
|
*/
|
||||||
|
class Manage extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
|
&& defined('ACTIVITY_REPORT')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& dcCore::app()->auth?->check(dcCore::app()->auth->makePermissions([
|
||||||
|
dcAuth::PERMISSION_ADMIN,
|
||||||
|
]), dcCore::app()->blog?->id);
|
||||||
|
|
||||||
if ($super) {
|
return static::$init;
|
||||||
dcCore::app()->activityReport->setGlobal();
|
|
||||||
}
|
|
||||||
|
|
||||||
$logs = dcCore::app()->activityReport->getLogs([]);
|
|
||||||
|
|
||||||
if ($super) {
|
|
||||||
$breadcrumb = [
|
|
||||||
__('Current blog') => dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['super' => 0]),
|
|
||||||
'<span class="page-title">' . __('All blogs') . '</span>' => '',
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
$breadcrumb = ['<span class="page-title">' . __('Current blog') . '</span>' => ''];
|
|
||||||
if (dcCore::app()->auth->isSuperAdmin()) {
|
|
||||||
$breadcrumb[__('All blogs')] = dcCore::app()->adminurl->get('admin.plugin.' . basename(__DIR__), ['super' => 1]);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
echo '<html><head><title>' . __('Activity report') . '</title></head><body>' .
|
public static function process(): bool
|
||||||
dcPage::breadcrumb(array_merge([__('Activity report') => '', __('Logs') => ''], $breadcrumb), ['hl' => false]) .
|
{
|
||||||
dcPage::notices();
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
if ($logs->isEmpty()) {
|
|
||||||
echo '<p>' . __('No log') . '</p>';
|
|
||||||
} else {
|
|
||||||
echo '
|
|
||||||
<div class="table-outer"><table><thead>
|
|
||||||
<tr>
|
|
||||||
<th>' . __('Action') . '</th>
|
|
||||||
<th>' . __('Message') . '</th>
|
|
||||||
<th>' . __('Date') . '</th>';
|
|
||||||
if ($super) {
|
|
||||||
echo '<th>' . __('Blog') . '</th>';
|
|
||||||
}
|
|
||||||
echo '</tr></thead><tbody>';
|
|
||||||
|
|
||||||
while ($logs->fetch()) {
|
|
||||||
$action = dcCore::app()->activityReport->getGroups($logs->activity_group, $logs->activity_action);
|
|
||||||
|
|
||||||
if (empty($action)) {
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$off = $super && $logs->activity_blog_status == 1 ? ' offline' : '';
|
if (!empty($_POST['delete_all_logs']) || !empty($_POST['delete_reported_logs'])) {
|
||||||
$date = dt::str(
|
try {
|
||||||
dcCore::app()->blog->settings->system->date_format . ', ' . dcCore::app()->blog->settings->system->time_format,
|
ActivityReport::instance()->deleteLogs(!empty($_POST['delete_reported_logs']));
|
||||||
strtotime($logs->activity_dt),
|
dcPage::addSuccessNotice(__('Logs successfully deleted'));
|
||||||
dcCore::app()->auth->getInfo('user_tz')
|
dcCore::app()->adminurl?->redirect('admin.plugin.' . My::id());
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function render(): void
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$logs = $counter = $list = null;
|
||||||
|
$filter = new adminGenericFilter(dcCore::app(), My::id());
|
||||||
|
$params = new ArrayObject($filter->params());
|
||||||
|
|
||||||
|
try {
|
||||||
|
$logs = ActivityReport::instance()->getLogs($params);
|
||||||
|
$counter = ActivityReport::instance()->getLogs($params, true);
|
||||||
|
if (!is_null($logs) && !is_null($counter)) {
|
||||||
|
$list = new ManageList(dcCore::app(), $logs, $counter->f(0));
|
||||||
|
}
|
||||||
|
} catch (Exception $e) {
|
||||||
|
dcCore::app()->error->add($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::openModule(
|
||||||
|
My::name(),
|
||||||
|
$filter->js((string) dcCore::app()->adminurl?->get('admin.plugin.' . My::id())) .
|
||||||
|
dcPage::jsJson(My::id(), ['confirm_delete' => __('Are you sure you want to delete logs?')]) .
|
||||||
|
dcPage::jsModuleLoad(My::id() . '/js/backend.js') .
|
||||||
|
|
||||||
|
# --BEHAVIOR-- activityReportListHeader --
|
||||||
|
dcCore::app()->callBehavior('activityReportListHeader')
|
||||||
);
|
);
|
||||||
$msg = vsprintf(__($action['msg']), dcCore::app()->activityReport->decode($logs->activity_logs));
|
|
||||||
|
|
||||||
echo '
|
echo
|
||||||
<tr class="line' . $off . '">
|
dcPage::breadcrumb([
|
||||||
<td class="nowrap">' . __($action['title']) . '</td>
|
__('Plugins') => '',
|
||||||
<td class="maximal">' . $msg . '</td>
|
My::name() => '',
|
||||||
<td class="nowrap">' . $date . '</td>';
|
]) .
|
||||||
if ($super) {
|
dcPage::notices();
|
||||||
echo '<td class="nowrap">' . $logs->blog_id . '</td>';
|
|
||||||
|
if (!is_null($list)) {
|
||||||
|
$filter->display('admin.plugin.' . My::id(), (new Hidden('p', My::id()))->render());
|
||||||
|
$list->logsDisplay($filter, '%s');
|
||||||
}
|
}
|
||||||
echo '</tr>';
|
|
||||||
}
|
|
||||||
echo '</tbody></table></div>';
|
|
||||||
}
|
|
||||||
dcCore::app()->activityReport->unsetGlobal();
|
|
||||||
|
|
||||||
echo '</body></html>';
|
if (!is_null($logs) && !$logs->isEmpty()) {
|
||||||
|
echo
|
||||||
|
(new Form('form-logs'))->method('post')->action(dcCore::app()->admin->getPageURL())->fields([
|
||||||
|
(new Para())->class('right')->separator(' ')->items([
|
||||||
|
(new Submit('delete_all_logs'))->class('delete')->value(__('Delete all aticivity logs')),
|
||||||
|
(new Submit('delete_reported_logs'))->class('delete')->value(__('Delete all allready reported logs')),
|
||||||
|
dcCore::app()->formNonce(false),
|
||||||
|
]),
|
||||||
|
])->render();
|
||||||
|
}
|
||||||
|
|
||||||
|
dcPage::closeModule();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
102
src/ManageList.php
Normal file
102
src/ManageList.php
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use adminGenericFilter;
|
||||||
|
use adminGenericList;
|
||||||
|
use dcCore;
|
||||||
|
use dcPager;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs admin list helper.
|
||||||
|
*/
|
||||||
|
class ManageList extends adminGenericList
|
||||||
|
{
|
||||||
|
public function logsDisplay(adminGenericFilter $filter, string $enclose_block = ''): void
|
||||||
|
{
|
||||||
|
if (!$this->rs || $this->rs->isEmpty()) {
|
||||||
|
if ($filter->show()) {
|
||||||
|
echo '<p><strong>' . __('No log matches the filter') . '</strong></p>';
|
||||||
|
} else {
|
||||||
|
echo '<p><strong>' . __('No log') . '</strong></p>';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$pager = new dcPager((int) $filter->value('page'), (int) $this->rs_count, (int) $filter->value('nb'), 10);
|
||||||
|
$pager->var_page = 'page';
|
||||||
|
|
||||||
|
$html_block = '<div class="table-outer"><table><caption>' . (
|
||||||
|
$filter->show() ?
|
||||||
|
sprintf(__('List of %s logs matching the filter.'), $this->rs_count) :
|
||||||
|
sprintf(__('List of %s logs.'), $this->rs_count)
|
||||||
|
) . '</caption>';
|
||||||
|
|
||||||
|
$cols = new ArrayObject([
|
||||||
|
'activity_group' => '<th scope="col" class="nowrap">' . __('Group') . '</th>',
|
||||||
|
'activity_action' => '<th scope="col" class="nowrap">' . __('Action') . '</th>',
|
||||||
|
'activity_logs' => '<th scope="col" class="nowrap">' . __('Message') . '</th>',
|
||||||
|
'activity_date' => '<th scope="col" class="nowrap">' . __('Date') . '</th>',
|
||||||
|
'activity_status' => '<th scope="col" class="nowrap">' . __('Status') . '</th>',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->userColumns(My::id(), $cols);
|
||||||
|
|
||||||
|
$html_block .= '<tr>' . implode(iterator_to_array($cols)) . '</tr>%s</table>%s</div>';
|
||||||
|
if ($enclose_block) {
|
||||||
|
$html_block = sprintf($enclose_block, $html_block);
|
||||||
|
}
|
||||||
|
$blocks = explode('%s', $html_block);
|
||||||
|
|
||||||
|
echo $pager->getLinks() . $blocks[0];
|
||||||
|
|
||||||
|
while ($this->rs->fetch()) {
|
||||||
|
echo $this->logsLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
echo $blocks[1] . $blocks[2] . $pager->getLinks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function logsLine(): string
|
||||||
|
{
|
||||||
|
$offline = (int) $this->rs->f('activity_status') == ActivityReport::STATUS_REPORTED ? ' offline' : '';
|
||||||
|
$group = ActivityReport::instance()->groups->get($this->rs->f('activity_group'));
|
||||||
|
$action = $group->get($this->rs->f('activity_action'));
|
||||||
|
$message = json_decode((string) $this->rs->f('activity_logs'), true);
|
||||||
|
$message = $message[0] == 'undefined' ? __('undefined') : vsprintf(__($action->message), $message);
|
||||||
|
$date = Date::str(
|
||||||
|
dcCore::app()->blog?->settings->get('system')->get('date_format') . ', ' . dcCore::app()->blog?->settings->get('system')->get('time_format'),
|
||||||
|
(int) strtotime((string) $this->rs->f('activity_dt')),
|
||||||
|
dcCore::app()->auth?->getInfo('user_tz')
|
||||||
|
);
|
||||||
|
$status = (int) $this->rs->f('activity_status') == ActivityReport::STATUS_PENDING ? __('pending') : __('reported');
|
||||||
|
|
||||||
|
$cols = new ArrayObject([
|
||||||
|
'activity_group' => '<td class="nowrap">' . __($group->title) . '</td>',
|
||||||
|
'activity_action' => '<td class="nowrap">' . __($action->title) . '</td>',
|
||||||
|
'activity_logs' => '<td class="maximal">' . $message . '</td>',
|
||||||
|
'activity_date' => '<td class="nowrap">' . $date . '</td>',
|
||||||
|
'activity_status' => '<td class="nowrap">' . $status . '</td>',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->userColumns(My::id(), $cols);
|
||||||
|
|
||||||
|
return
|
||||||
|
'<tr class="line ' . $offline . '" id="l' . $this->rs->f('activity_id') . '">' .
|
||||||
|
implode(iterator_to_array($cols)) .
|
||||||
|
'</tr>';
|
||||||
|
}
|
||||||
|
}
|
77
src/My.php
Normal file
77
src/My.php
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module definitions
|
||||||
|
*/
|
||||||
|
class My
|
||||||
|
{
|
||||||
|
/** @var string Required php version */
|
||||||
|
public const PHP_MIN = '8.1';
|
||||||
|
|
||||||
|
/** @var string Activity database table name */
|
||||||
|
public const ACTIVITY_TABLE_NAME = 'activity';
|
||||||
|
|
||||||
|
/** @var string Cache sub directory name */
|
||||||
|
public const CACHE_DIR_NAME = 'activityreport';
|
||||||
|
|
||||||
|
/** @var int Incremental version by breaking changes */
|
||||||
|
public const COMPATIBILITY_VERSION = 3;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module id.
|
||||||
|
*/
|
||||||
|
public static function id(): string
|
||||||
|
{
|
||||||
|
return basename(dirname(__DIR__));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module name.
|
||||||
|
*/
|
||||||
|
public static function name(): string
|
||||||
|
{
|
||||||
|
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module root.
|
||||||
|
*/
|
||||||
|
public static function root(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check is module is trully installed.
|
||||||
|
*
|
||||||
|
* Required as table structrue has changed
|
||||||
|
*/
|
||||||
|
public static function isInstalled(): bool
|
||||||
|
{
|
||||||
|
return dcCore::app()->getVersion(self::id()) == dcCore::app()->plugins->moduleInfo(self::id(), 'version');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check php version.
|
||||||
|
*/
|
||||||
|
public static function phpCompliant(): bool
|
||||||
|
{
|
||||||
|
return version_compare(phpversion(), self::PHP_MIN, '>=');
|
||||||
|
}
|
||||||
|
}
|
@ -10,30 +10,58 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Clearbricks::lib()->autoload([
|
namespace Dotclear\Plugin\activityReport;
|
||||||
'activityReport' => __DIR__ . '/inc/class.activity.report.php',
|
|
||||||
'activityReportBehaviors' => __DIR__ . '/inc/class.activity.report.behaviors.php',
|
|
||||||
]);
|
|
||||||
|
|
||||||
try {
|
use dcCore;
|
||||||
if (!defined('ACTIVITY_REPORT_V2')) {
|
use dcNsProcess;
|
||||||
dcCore::app()->__set('activityReport', new activityReport());
|
use Exception;
|
||||||
|
|
||||||
dcCore::app()->url->register(
|
/**
|
||||||
basename(__DIR__),
|
* Prepend process.
|
||||||
'reports',
|
*/
|
||||||
'^reports/((atom|rss2)/(.+))$',
|
class Prepend extends dcNsProcess
|
||||||
['activityReportPublicUrl', 'feed']
|
{
|
||||||
);
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_RC_PATH')
|
||||||
|
&& My::phpCompliant()
|
||||||
|
&& My::isInstalled();
|
||||||
|
|
||||||
define('ACTIVITY_REPORT_V2', true);
|
return static::$init;
|
||||||
|
}
|
||||||
activityReportBehaviors::registerBehaviors();
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defined('ACTIVITY_REPORT')) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// launch once activity report stuff
|
||||||
|
ActivityReport::instance();
|
||||||
|
|
||||||
|
// regirster activity feed URL
|
||||||
|
dcCore::app()->url->register(
|
||||||
|
My::id(),
|
||||||
|
'reports',
|
||||||
|
'^reports/((atom|rss2)/(.+))$',
|
||||||
|
[UrlHandler::class, 'feed']
|
||||||
|
);
|
||||||
|
|
||||||
|
// declare report open
|
||||||
|
define('ACTIVITY_REPORT', My::COMPATIBILITY_VERSION);
|
||||||
|
|
||||||
|
// register predefined activities scan
|
||||||
|
ActivityBehaviors::register();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
|
||||||
//throw new Exception('Failed to launch activityReport');
|
|
||||||
}
|
}
|
||||||
|
113
src/Settings.php
Normal file
113
src/Settings.php
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use Exception;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module settings helper.
|
||||||
|
*/
|
||||||
|
class Settings
|
||||||
|
{
|
||||||
|
/** @var bool $feed_active The activity feed activation */
|
||||||
|
public readonly bool $feed_active;
|
||||||
|
|
||||||
|
/** @var int $obsolete The logs obsolete time */
|
||||||
|
public readonly int $obsolete;
|
||||||
|
|
||||||
|
/** @var int $interval The report interval time */
|
||||||
|
public readonly int $interval;
|
||||||
|
|
||||||
|
/** @var int $lastreport The last report time */
|
||||||
|
public readonly int $lastreport;
|
||||||
|
|
||||||
|
/** @var array $mailinglist The mailing list */
|
||||||
|
public readonly array $mailinglist;
|
||||||
|
|
||||||
|
/** @var string $mailformat The mail content format */
|
||||||
|
public readonly string $mailformat;
|
||||||
|
|
||||||
|
/** @var string $date format The date format */
|
||||||
|
public readonly string $dateformat;
|
||||||
|
|
||||||
|
/** @var array $requests The selected actions list to report */
|
||||||
|
public readonly array $requests;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor sets settings properties.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
if (dcCore::app()->blog === null) {
|
||||||
|
throw new Exception('Blog is not set');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->feed_active = (bool) ($this->get('feed_active') ?? false);
|
||||||
|
$this->obsolete = (int) ($this->get('obsolete') ?? 2419200);
|
||||||
|
$this->interval = (int) ($this->get('interval') ?? 86400);
|
||||||
|
$this->lastreport = (int) ($this->get('lastreport') ?? 0);
|
||||||
|
$this->mailinglist = (array) ($this->get('mailinglist') ?? []);
|
||||||
|
$this->mailformat = (string) ($this->get('mailformat') ?? 'plain');
|
||||||
|
$this->dateformat = (string) ($this->get('dateformat') ?? '%Y-%m-%d %H:%M:%S');
|
||||||
|
$this->requests = (array) ($this->get('requests') ?? []);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dump properties.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed> The settings properties
|
||||||
|
*/
|
||||||
|
public function dump(): array
|
||||||
|
{
|
||||||
|
$vars = get_class_vars(__CLASS__);
|
||||||
|
|
||||||
|
return $vars ? $vars : [];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a setting in database.
|
||||||
|
*
|
||||||
|
* Setting is modified in database but not in script !
|
||||||
|
*
|
||||||
|
* @param string $key The setting key
|
||||||
|
* @param mixed $value The setting value
|
||||||
|
*/
|
||||||
|
public function set(string $key, mixed $value): void
|
||||||
|
{
|
||||||
|
if (property_exists($this, $key) && gettype($value) == gettype($this->{$key})) {
|
||||||
|
dcCore::app()->blog?->settings->get(My::id())->put(
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
gettype($value),
|
||||||
|
null,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a setting from database.
|
||||||
|
*
|
||||||
|
* @param string $key The setting key
|
||||||
|
*
|
||||||
|
* @return mixed The setting value
|
||||||
|
*/
|
||||||
|
private function get(string $key): mixed
|
||||||
|
{
|
||||||
|
return dcCore::app()->blog?->settings->get(My::id())->get($key);
|
||||||
|
}
|
||||||
|
}
|
161
src/Template.php
Normal file
161
src/Template.php
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use ArrayObject;
|
||||||
|
use dcCore;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Template blocs and values.
|
||||||
|
*/
|
||||||
|
class Template
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* tpl:activityReports [attributes] : Activity report logs (tpl block)
|
||||||
|
*
|
||||||
|
* attributes:
|
||||||
|
*
|
||||||
|
* - lastn integer Limit to last n logs
|
||||||
|
* - ingnore_pagination 1|0 Ignore pagination paramaters
|
||||||
|
*
|
||||||
|
* @param ArrayObject $attr The attributes
|
||||||
|
* @param string $content The content
|
||||||
|
*
|
||||||
|
* @return string The code
|
||||||
|
*/
|
||||||
|
public static function activityReports(ArrayObject $attr, string $content): string
|
||||||
|
{
|
||||||
|
$lastn = 0;
|
||||||
|
if (isset($attr['lastn'])) {
|
||||||
|
$lastn = abs((int) $attr['lastn']) + 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$p = '$_page_number = dcCore::app()->public->getPageNumber(); if ($_page_number < 1) { $_page_number = 1; }' . "\n\$params = new ArrayObject();\n";
|
||||||
|
|
||||||
|
if ($lastn > 0) {
|
||||||
|
$p .= "\$params['limit'] = " . $lastn . ";\n";
|
||||||
|
} else {
|
||||||
|
$p .= "\$params['limit'] = dcCore::app()->ctx->nb_entry_per_page;\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($attr['ignore_pagination']) || $attr['ignore_pagination'] == '0') {
|
||||||
|
$p .= "\$params['limit'] = array(((\$_page_number-1)*\$params['limit']),\$params['limit']);\n";
|
||||||
|
} else {
|
||||||
|
$p .= "\$params['limit'] = array(0, \$params['limit']);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
"<?php \n" .
|
||||||
|
$p .
|
||||||
|
'dcCore::app()->ctx->activityreport_params = $params; ' . "\n" .
|
||||||
|
'dcCore::app()->ctx->activityreports = ' . ActivityReport::class . '::instance()->getLogs($params); unset($params); ' . "\n" .
|
||||||
|
'while (dcCore::app()->ctx->activityreports->fetch()) : ?>' . $content . '<?php endwhile; ' .
|
||||||
|
'dcCore::app()->ctx->pop("activityreports"); dcCore::app()->ctx->pop("activityreport_params"); ' . "\n" .
|
||||||
|
'?>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpl:activityReportFeedID [attributes] : Activity report feed ID (tpl value)
|
||||||
|
*
|
||||||
|
* attributes:
|
||||||
|
*
|
||||||
|
* - any filters See self::getFilters()
|
||||||
|
*
|
||||||
|
* @param ArrayObject $attr The attributes
|
||||||
|
*
|
||||||
|
* @return string The code
|
||||||
|
*/
|
||||||
|
public static function activityReportFeedID(ArrayObject $attr): string
|
||||||
|
{
|
||||||
|
return
|
||||||
|
'urn:md5:<?php echo md5(dcCore::app()->ctx->activityreports->blog_id.' .
|
||||||
|
'dcCore::app()->ctx->activityreports->activity_id.dcCore::app()->ctx->activityreports->activity_dt); ' .
|
||||||
|
'?>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpl:activityReportTitle [attributes] : Activity report log title (tpl value)
|
||||||
|
*
|
||||||
|
* attributes:
|
||||||
|
*
|
||||||
|
* - any filters See self::getFilters()
|
||||||
|
*
|
||||||
|
* @param ArrayObject $attr The attributes
|
||||||
|
*
|
||||||
|
* @return string The code
|
||||||
|
*/
|
||||||
|
public static function activityReportTitle(ArrayObject $attr): string
|
||||||
|
{
|
||||||
|
$f = dcCore::app()->tpl->getFilters($attr);
|
||||||
|
|
||||||
|
return '<?php echo ' . sprintf($f, Context::class . '::parseTitle()') . '; ?>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpl:activityReportContent [attributes] : Activity report log message (tpl value)
|
||||||
|
*
|
||||||
|
* attributes:
|
||||||
|
*
|
||||||
|
* - any filters See self::getFilters()
|
||||||
|
*
|
||||||
|
* @param ArrayObject $attr The attributes
|
||||||
|
*
|
||||||
|
* @return string The code
|
||||||
|
*/
|
||||||
|
public static function activityReportContent(ArrayObject $attr): string
|
||||||
|
{
|
||||||
|
$f = dcCore::app()->tpl->getFilters($attr);
|
||||||
|
|
||||||
|
return '<?php echo ' . sprintf($f, Context::class . '::parseContent()') . '; ?>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tpl:activityReportDate [attributes] : Activity report log date (tpl value)
|
||||||
|
*
|
||||||
|
* attributes:
|
||||||
|
*
|
||||||
|
* - format Use Date::str() (if iso8601 nor rfc822 were specified default to %Y-%m-%d %H:%M:%S)
|
||||||
|
* - iso8601 (1|0) Use Date::iso8601()
|
||||||
|
* - rfc822 (1|0) Use Date::rfc822()
|
||||||
|
* - any filters See self::getFilters()
|
||||||
|
*
|
||||||
|
* @param ArrayObject $attr The attributes
|
||||||
|
*
|
||||||
|
* @return string The code
|
||||||
|
*/
|
||||||
|
public static function activityReportDate(ArrayObject $attr): string
|
||||||
|
{
|
||||||
|
$format = '';
|
||||||
|
if (!empty($attr['format'])) {
|
||||||
|
$format = addslashes($attr['format']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$iso8601 = !empty($attr['iso8601']);
|
||||||
|
$rfc822 = !empty($attr['rfc822']);
|
||||||
|
|
||||||
|
$f = dcCore::app()->tpl->getFilters($attr);
|
||||||
|
|
||||||
|
if ($rfc822) {
|
||||||
|
return '<?php echo ' . sprintf($f, Date::class . '::rfc822(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>';
|
||||||
|
} elseif ($iso8601) {
|
||||||
|
return '<?php echo ' . sprintf($f, Date::class . '::iso8601(strtotime(dcCore::app()->ctx->activityreports->activity_dt),dcCore::app()->blog->settings->system->blog_timezone)') . '; ?>';
|
||||||
|
} elseif (!empty($format)) {
|
||||||
|
return '<?php echo ' . sprintf($f, Date::class . "::dt2str('" . $format . "',dcCore::app()->ctx->activityreports->activity_dt)") . '; ?>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<?php echo ' . sprintf($f, Date::class . '::dt2str(dcCore::app()->blog->settings->system->date_format,dcCore::app()->ctx->activityreports->activity_dt)') . '; ?>';
|
||||||
|
}
|
||||||
|
}
|
@ -10,72 +10,78 @@
|
|||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_CONTEXT_ADMIN')) {
|
declare(strict_types=1);
|
||||||
return null;
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Plugin\Uninstaller\Uninstaller;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Uninstall process.
|
||||||
|
*
|
||||||
|
* Using plugin Uninstaller
|
||||||
|
*/
|
||||||
|
class Uninstall extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN');
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uninstaller::instance()
|
||||||
|
->addUserAction(
|
||||||
|
'tables',
|
||||||
|
'delete',
|
||||||
|
My::ACTIVITY_TABLE_NAME
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'tables',
|
||||||
|
'delete',
|
||||||
|
My::ACTIVITY_TABLE_NAME
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
// no custom action
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'tables',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
initActivityReport::ACTIVITY_TABLE_NAME,
|
|
||||||
/* description */
|
|
||||||
sprintf(__('delete %s table'), '"activity"')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'tables',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
initActivityReport::SETTING_TABLE_NAME,
|
|
||||||
/* description */
|
|
||||||
sprintf(__('delete %s table'), '"activity_setting"')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'plugins',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* description */
|
|
||||||
__('delete plugin files')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addUserAction(
|
|
||||||
/* type */
|
|
||||||
'versions',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* description */
|
|
||||||
__('delete the version number')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addDirectAction(
|
|
||||||
/* type */
|
|
||||||
'versions',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* description */
|
|
||||||
sprintf(__('delete %s version number'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->addDirectAction(
|
|
||||||
/* type */
|
|
||||||
'plugins',
|
|
||||||
/* action */
|
|
||||||
'delete',
|
|
||||||
/* ns */
|
|
||||||
basename(__DIR__),
|
|
||||||
/* description */
|
|
||||||
sprintf(__('delete %s plugin files'), basename(__DIR__))
|
|
||||||
);
|
|
||||||
|
56
src/UrlHandler.php
Normal file
56
src/UrlHandler.php
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief activityReport, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Jean-Christian Denis and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\activityReport;
|
||||||
|
|
||||||
|
use context;
|
||||||
|
use dcCore;
|
||||||
|
use dcUrlHandlers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frontend URL handler.
|
||||||
|
*/
|
||||||
|
class UrlHandler extends dcUrlHandlers
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get activity logs feed.
|
||||||
|
*
|
||||||
|
* @param null|string $args The URL arguments
|
||||||
|
*/
|
||||||
|
public static function feed(?string $args): void
|
||||||
|
{
|
||||||
|
// no context or wrong URL args or module no loaded or report unactive
|
||||||
|
if (!dcCore::app()->ctx
|
||||||
|
|| !preg_match('/^(atom|rss2)\/(.+)$/', (string) $args, $m)
|
||||||
|
|| !defined('ACTIVITY_REPORT')
|
||||||
|
|| !ActivityReport::instance()->settings->feed_active
|
||||||
|
) {
|
||||||
|
self::p404();
|
||||||
|
}
|
||||||
|
|
||||||
|
// get type of feed
|
||||||
|
$mime = $m[1] == 'atom' ? 'application/atom+xml' : 'application/xml';
|
||||||
|
if (false === ActivityReport::instance()->checkUserCode($m[2])) {
|
||||||
|
self::p404();
|
||||||
|
}
|
||||||
|
|
||||||
|
// feed limits
|
||||||
|
dcCore::app()->ctx->__set('nb_entry_per_page', (int) dcCore::app()->blog?->settings->get('system')->get('nb_post_per_feed'));
|
||||||
|
dcCore::app()->ctx->__set('short_feed_items', (int) dcCore::app()->blog?->settings->get('system')->get('short_feed_items'));
|
||||||
|
|
||||||
|
// serve activity feed template
|
||||||
|
header('X-Robots-Tag: ' . context::robotsPolicy(dcCore::app()->blog?->settings->get('system')->get('robots_policy'), ''));
|
||||||
|
self::serveDocument('activityreport-' . $m[1] . '.xml', $mime);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user