Skip to content

Bugfixes and PHP 8 fixes #74

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: refactor
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,16 @@ class Client extends \IXR_Client {
* @param int $timeout
*/
public function __construct($server, $user, $pass, $timeout = 15) {
parent::__construct($server);
$this->timeout = $timeout;
parent::__construct($server, $path = false, $port = 80, $timeout);
$this->login($user, $pass);
}

/** @inheritdoc */
public function query() {
public function query(...$args) {
$ok = call_user_func_array('parent::query', func_get_args());
$code = $this->getErrorCode();
if($code === -32300) $code = -1 * $this->status; // use http status on transport errors
$code = @$this->getErrorCode();
$http = $this->getHTTPClient();
if($code === -32300) $code = -1 * $http->status; // use http status on transport errors
if(!$ok) {
// when a file context is given include it in the exception
if($this->filecontext) {
Expand Down
68 changes: 44 additions & 24 deletions Profile.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace dokuwiki\plugin\sync;

use dokuwiki\Utf8\Sort;

class Profile {

const DIR_PULL = -1;
Expand Down Expand Up @@ -31,6 +33,7 @@ public function __construct($config) {
$this->config = $config;

$this->syncoptions = [
'pattern' => '',
'depth' => (int) $config['depth'],
'hash' => true,
];
Expand Down Expand Up @@ -261,13 +264,14 @@ protected function setRemoteLock($id, $state) {
*/
protected function fetchRemoteFileList($type) {
if($type === self::TYPE_PAGES) {
$cmd = 'dokuwiki.getPagelist';
$cmd = 'core.listPages';
$this->client->query($cmd, $this->config['ns'], $this->syncoptions['depth'], $this->syncoptions['hash']);
} else {
$cmd = 'wiki.getAttachments';
$cmd = 'core.listMedia';
$this->client->query($cmd, $this->config['ns'], $this->syncoptions['pattern'], $this->syncoptions['depth'], $this->syncoptions['hash']);
}

$this->client->query($cmd, $this->config['ns'], $this->syncoptions);
$remote = $this->client->getResponse();
$remote = @$this->client->getResponse();

// put into synclist
foreach($remote as $item) {
Expand All @@ -291,9 +295,16 @@ protected function fetchLocalFileList($type) {
$cmd = 'search_media';
}

$syncoptions = $this->syncoptions;
if($type === self::TYPE_PAGES) {
if($syncoptions['depth']) {
$syncoptions['depth'] += substr_count($this->config['ns'], ':') + 1;
}
}

$local = array();
$dir = utf8_encodeFN(str_replace(':', '/', $this->config['ns']));
search($local, $basedir, $cmd, $this->syncoptions, $dir);
search($local, $basedir, $cmd, $syncoptions, $dir);

// put into synclist
foreach($local as $item) {
Expand All @@ -308,7 +319,11 @@ protected function fetchLocalFileList($type) {
* @return mixed
*/
protected function itemEnhance($item) {
$item['info'] = dformat($item['mtime']) . '<br />' . filesize_h($item['size']);
if(isset($item['mtime'])) {
$item['info'] = dformat($item['mtime']) . '<br />' . filesize_h($item['size']);
} else {
$item['info'] = dformat($item['revision']) . '<br />' . filesize_h($item['size']);
}
return $item;
}

Expand All @@ -317,42 +332,47 @@ protected function itemEnhance($item) {
*/
protected function consolidateSyncList() {
// synctimes
$ltime = (int) $this->config['ltime'];
$rtime = (int) $this->config['rtime'];
$letime = (int) $this->config['letime'];
$retime = (int) $this->config['retime'];
$ltime = isset($this->config['ltime']) ? (int) $this->config['ltime'] : null;
$rtime = isset($this->config['rtime']) ? (int) $this->config['rtime'] : null;
$letime = isset($this->config['letime']) ? (int) $this->config['letime'] : null;
$retime = isset($this->config['retime']) ? (int) $this->config['retime'] : null;

foreach([self::TYPE_PAGES, self::TYPE_MEDIA] as $type) {
foreach($this->synclist[$type] as $id => $item) {
// no sync if hashes match
if($item['remote']['hash'] == $item['local']['hash']) {
unset($this->synclist[$type][$id]);
continue;
if(isset($item['remote']['hash']) && isset($item['local']['hash'])) {
if($item['remote']['hash'] == $item['local']['hash']) {
unset($this->synclist[$type][$id]);
continue;
}
}

// check direction
$dir = self::DIR_NONE;
if($ltime && $rtime) { // synced before
if($item['remote']['mtime'] > $rtime &&
$item['local']['mtime'] <= $letime
) {
$dir = self::DIR_PULL;
}
if($item['remote']['mtime'] <= $retime &&
$item['local']['mtime'] > $ltime
) {
$dir = self::DIR_PUSH;
if(isset($item['local']['mtime']) && isset($item['remote']['revision'])) {
if($item['remote']['revision'] > $rtime &&
$item['local']['mtime'] <= $letime
) {
$dir = self::DIR_PULL;
}
if($item['remote']['revision'] <= $retime &&
$item['local']['mtime'] > $ltime
) {
$dir = self::DIR_PUSH;
}
}
} else { // never synced
if(!$item['local']['mtime'] && $item['remote']['mtime']) {
if(!isset($item['local']['mtime']) && $item['remote']['revision']) {
$dir = self::DIR_PULL;
}
if($item['local']['mtime'] && !$item['remote']['mtime']) {
if((isset($item['local']['mtime']) && $item['local']['mtime']) && !isset($item['remote']['revision'])) {
$dir = self::DIR_PUSH;
}
}
$this->synclist[$type][$id]['dir'] = $dir;
}
Sort::ksort($this->synclist[$type]);
}
}

Expand Down
2 changes: 1 addition & 1 deletion SyncException.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public function __construct($message = '', $code = 0, $previous = null) {

if($code === -403) $message = $plugin->getLang('autherr');

parent::__construct($message, $code, $previous);
parent::__construct(html_entity_decode($message), $code, $previous);
}
}
2 changes: 1 addition & 1 deletion SyncFileException.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ public function __construct($message, $id, $code = 0) {

// append file name
$message = $message . ' ' . $id;
parent::__construct($message, $code);
parent::__construct(html_entity_decode($message), $code);
}
}
4 changes: 2 additions & 2 deletions admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@ function handle() {
$this->profileManager->deleteProfileConfig($this->profno);
$this->profno = false;
$INPUT->remove('prf');
msg('profile deleted', 1);
msg($this->getLang('profiledeleted'), 1);
} else {
// profile add/edit
$this->profno = $this->profileManager->setProfileConfig($this->profno, $profile);
msg('profile saved', 1);
msg($this->getLang('profilesaved'), 1);
}
} catch(SyncException $e) {
msg(hsc($e->getMessage()), -1);
Expand Down
3 changes: 3 additions & 0 deletions lang/en/lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
$lang['lockfail'] = 'couldn\'t lock and will skip:';
$lang['localdelfail'] = 'local delete failed:';

$lang['profilesaved'] = 'profile saved.';
$lang['profiledeleted'] = 'profile deleted.';

$lang['js']['list'] = 'A list of files that differ between your local and the remote wiki is shown below. You need to decide which revisions you want to keep.'; #from list.txt

$lang['js']['file'] = 'Page or Media File';
Expand Down
4 changes: 4 additions & 0 deletions lang/pt-br/intro.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
====== Sincronização do Wiki ======

Esta ferramenta permite sincronizar o conteúdo do seu wiki com outros wikis. Vários outros wikis podem ser configurados usando perfis de sincronização. A sincronização pode ser restrita a determinados namespaces.

70 changes: 70 additions & 0 deletions lang/pt-br/lang.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

$lang['menu'] = 'Sincronizar Wikis';

$lang['syncstart'] = 'Iniciar Sincronização';
$lang['lastsync'] = 'Última Sincronização:';
$lang['remotever'] = 'Versão do Wiki Remoto:';

$lang['autherr'] = 'O usuário fornecido não tem permissão para acessar a API XMLRPC no wiki remoto.';
$lang['loginerr'] = 'Falha ao fazer login no wiki remoto. Certifique-se de que as credenciais fornecidas sejam válidas no wiki remoto.';
$lang['versionerr'] = 'A versão da API XMLRPC do wiki remoto é muito antiga. Você precisa atualizar o wiki remoto para usar o plugin de sincronização.';

$lang['neversync'] = 'Este perfil nunca foi sincronizado antes.';
$lang['profile'] = 'Sincronizar Perfil';
$lang['newprofile'] = 'Novo Perfil...';
$lang['select'] = 'Selecionar';
$lang['create'] = 'Criar novo Perfil de Sincronização';
$lang['edit'] = 'Editar Perfil de Sincronização';
$lang['delete'] = 'Excluir Perfil de Sincronização';

$lang['server'] = 'URL do XMLRPC';
$lang['user'] = 'Nome de usuário';
$lang['pass'] = 'Senha';
$lang['ns'] = 'Namespace';
$lang['depth'] = 'Profundidade de Sincronização';
$lang['level0'] = 'Todos os subnamespaces';
$lang['level1'] = 'Nenhum subnamespace';
$lang['level2'] = 'Namespace + 1 subnamespace';
$lang['level3'] = 'Namespace + 2 subnamespaces';
$lang['type'] = 'O que sincronizar';
$lang['type0'] = 'Tudo';
$lang['type1'] = 'Apenas páginas';
$lang['type2'] = 'Arquivos de mídia';


$lang['save'] = 'Salvar';
$lang['changewarn'] = 'Salvar novamente este perfil redefinirá os tempos de sincronização. Você precisará escolher manualmente as direções de sincronização para todos os arquivos na próxima sincronização.';

$lang['noconnect'] = 'Não foi possível conectar-se ao wiki remoto:';
$lang['lockfail'] = 'não foi possível bloquear e irá pular:';
$lang['localdelfail'] = 'falha na exclusão local:';

$lang['profilesaved'] = 'perfil salvo.';
$lang['profiledeleted'] = 'perfil excluído.';

$lang['js']['list'] = 'Uma lista de arquivos que diferem entre o wiki local e o remoto é mostrada abaixo. Você precisa decidir quais revisões deseja manter.'; #from list.txt

$lang['js']['file'] = 'Página ou Arquivo de Mídia';
$lang['js']['local'] = 'Wiki Local';
$lang['js']['remote'] = 'Wiki Remoto';
$lang['js']['diff'] = 'Diff';
$lang['js']['dir'] = 'Direção de Sincronização';

$lang['js']['push'] = 'Envie a revisão local para o wiki remoto.';
$lang['js']['pushdel'] = 'Exclua a revisão no wiki remoto.';
$lang['js']['pull'] = 'Extraia a revisão remota para o wiki local.';
$lang['js']['pulldel'] = 'Exclua a revisão local.';
$lang['js']['keep'] = 'Ignore este arquivo e mantenha ambas as revisões como estão.';

$lang['js']['insync'] = 'Não foram encontradas diferenças entre o seu wiki local e o wiki remoto. Não há necessidade de sincronizar.'; #from nochange.txt
$lang['js']['tosync'] = 'Sincronizando %d arquivos…';
$lang['js']['btn_done'] = 'Feito';
$lang['js']['btn_start'] = 'Iniciar';
$lang['js']['syncdone'] = 'Sincronização concluída.';
$lang['js']['loading'] = 'Recuperando lista de arquivos…';
$lang['js']['summary'] = 'Resumo';

$lang['timeout'] = 'Tempo limite';


20 changes: 19 additions & 1 deletion style.less
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

th.dir,
td.dir {
width: 6em;
width: 8.6em;
}

th.local,
Expand Down Expand Up @@ -108,5 +108,23 @@
content: url(pix/arrow-left-bold-circle.svg);
}
}

th.dir > label.push input {
&:checked::before {
content: url(pix/arrow-right-bold-circle-outline.svg);
}
}

th.dir > label.skip input {
&:checked::before {
content: url(pix/pause-circle-outline.svg);
}
}

th.dir > label.pull input {
&:checked::before {
content: url(pix/arrow-left-bold-circle-outline.svg);
}
}
}
}
30 changes: 28 additions & 2 deletions sync.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ jQuery(function () {
});
});
$output.append($table);
jQuery('input[name="dir"]').click(function(e){ sync_select(this.value); this.value = 0; });

var $lbl = jQuery('<label>');
$lbl.text(LANG.plugins.sync.summary + ': ');
Expand Down Expand Up @@ -59,6 +60,12 @@ jQuery(function () {
var $th = jQuery('<th>');
$th.addClass(l);
$th.text(LANG.plugins.sync[l]);
if(l == 'dir') {
$th.append('<br>');
$th.append('<label class="push"><input type="radio" name="dir" value="1" title="' + LANG.plugins.sync['push'] + '"></label>');
$th.append('<label class="skip"><input type="radio" name="dir" value="0" title="' + LANG.plugins.sync['skip'] + '"></label>');
$th.append('<label class="pull"><input type="radio" name="dir" value="-1" title="' + LANG.plugins.sync['pull'] + '"></label>');
}
$tr.append($th);
});
return $tr;
Expand Down Expand Up @@ -177,13 +184,31 @@ jQuery(function () {
return $html;
}

function sync_select(type) {
switch(type) {
case "1":
type = "push";
break;
case "0":
type = "skip";
break;
case "-1":
type = "pull";
break;
}
const types = ["push", "skip", "pull"];
if(types.includes(type)) {
jQuery('label[class='+type+'] input').prop('checked',true);
}
}

/**
* Start the sync process
*/
function beginsync() {
SYNC_DATA.items = [];

$output.find('tr').each(function (idx, tr) {
$output.find('tr[class^="type"]').each(function (idx, tr) {
var $tr = jQuery(tr);
var id = $tr.find('td').first().text();
var dir = parseInt($tr.find('input:checked').val(), 10);
Expand All @@ -193,6 +218,7 @@ jQuery(function () {
SYNC_DATA.items.push([id, type, dir]);
}
});
SYNC_DATA.items = SYNC_DATA.items.reverse();

SYNC_DATA.summary = $sum.val();

Expand Down Expand Up @@ -278,7 +304,7 @@ jQuery(function () {
*/
function error(error) {
var $err = jQuery('<div class="error">');
$err.text(error);
$err.text(error.responseText);
$output.append($err);
}

Expand Down