Esempio n. 1
0
 public function handle_action_act_preprocess(Doku_Event &$event, $param)
 {
     global $ID;
     global $TEXT;
     global $ACT;
     global $SUM;
     global $RANGE;
     global $REV;
     $act = $event->data;
     if ($act != 'dokutranslate_review') {
         $act = act_clean($act);
         $act = act_permcheck($act);
     }
     # Ignore drafts if the page is being translated
     # FIXME: Find a way to save $_REQUEST['parid'] into the draft
     if (@file_exists(metaFN($ID, '.translate')) && in_array($act, array('draft', 'recover'))) {
         act_draftdel('draftdel');
         $ACT = $act = 'edit';
     }
     if ($act == 'save') {
         # Take over save action if translation is in progress
         # or we're starting it
         if (!@file_exists(metaFN($ID, '.translate')) && empty($_REQUEST['translate'])) {
             return;
         }
         if (!checkSecurityToken()) {
             return;
         }
         # We're starting a translation
         if (!@file_exists(metaFN($ID, '.translate')) && !empty($_REQUEST['translate'])) {
             # Check if the user has permission to start
             # translation in this namespace
             if (!isModerator($ID)) {
                 return;
             }
             # Take the event over
             $event->stopPropagation();
             $event->preventDefault();
             # Save the data but exit if it fails
             $ACT = act_save($act);
             if ($ACT != 'show') {
                 return;
             }
             # Page was deleted, exit
             if (!@file_exists(wikiFN($ID))) {
                 return;
             }
             # Prepare data path
             $datapath = dataPath($ID);
             io_mkdir_p($datapath, 0755, true);
             # Backup the original page
             io_rename(wikiFN($ID), $datapath . '/orig.txt');
             # Backup old revisions
             $revisions = allRevisions($ID);
             foreach ($revisions as $rev) {
                 $tmp = wikiFN($ID, $rev);
                 io_rename($tmp, $datapath . '/' . basename($tmp));
             }
             # Backup meta files
             $metas = metaFiles($ID);
             foreach ($metas as $f) {
                 io_rename($f, $datapath . '/' . basename($f));
             }
             # Generate empty page to hold translated text
             $data = getCleanInstructions($datapath . '/orig.txt');
             saveWikiText($ID, genTranslateFile($data), $SUM, $_REQUEST['minor']);
             $translateMeta = genMeta(count($data));
             # create meta file for current translation state
             io_saveFile(metaFN($ID, '.translate'), serialize($translateMeta));
             # create separate meta file for translation history
             io_saveFile(metaFN($ID, '.translateHistory'), serialize(array('current' => $translateMeta)));
         } else {
             # Translation in progress, take the event over
             $event->preventDefault();
             # Save the data but exit if it fails
             $ACT = act_save($act);
             # Save failed, exit
             if ($ACT != 'show') {
                 return;
             }
             # Save successful, update translation metadata
             $lastrev = getRevisions($ID, 0, 1, 1024);
             updateMeta($ID, getParID(), $lastrev[0]);
         }
     } else {
         if ($act == 'revert') {
             # Take over save action if translation is in progress
             if (!@file_exists(metaFN($ID, '.translate'))) {
                 return;
             }
             if (!checkSecurityToken()) {
                 return;
             }
             # Translation in progress, take the event over
             $event->preventDefault();
             # Save the data but exit if it fails
             $revert = $REV;
             $ACT = act_revert($act);
             # Revert failed, exit
             if ($ACT != 'show') {
                 return;
             }
             # Revert successful, update translation metadata
             $lastrev = getRevisions($ID, 0, 1, 1024);
             updateMeta($ID, getParID(), $lastrev[0], $revert);
         } else {
             if (in_array($act, array('edit', 'preview'))) {
                 if (!@file_exists(metaFN($ID, '.translate')) || isset($TEXT)) {
                     return;
                 }
                 $parid = getParID();
                 $instructions = p_cached_instructions(wikiFN($ID));
                 $separators = array();
                 # Build array of paragraph separators
                 foreach ($instructions as $ins) {
                     if ($ins[0] == 'plugin' && $ins[1][0] == 'dokutranslate' && in_array($ins[1][1][0], array(DOKU_LEXER_ENTER, DOKU_LEXER_SPECIAL, DOKU_LEXER_EXIT))) {
                         $separators[] = $ins[1][1];
                     }
                 }
                 # Validate paragraph ID
                 if ($parid >= count($separators) - 1) {
                     $parid = 0;
                 }
                 # Build range for paragraph
                 $RANGE = strval($separators[$parid][2] + 1) . '-' . strval($separators[$parid + 1][1] - 1);
             } else {
                 if ($act == 'dokutranslate_review') {
                     # This action is mine
                     $event->stopPropagation();
                     $event->preventDefault();
                     # Show the page when done
                     $ACT = 'show';
                     # Load data
                     $meta = unserialize(io_readFile(metaFN($ID, '.translateHistory'), false));
                     $parid = getParID();
                     $writeRev = empty($REV) ? 'current' : intval($REV);
                     $writeRev = empty($meta[$writeRev][$parid]['changed']) ? $writeRev : $meta[$writeRev][$parid]['changed'];
                     $user = $_SERVER['REMOTE_USER'];
                     # Check for permission to write reviews
                     if (!canReview($ID, $meta[$writeRev], $parid)) {
                         return;
                     }
                     # Add review to meta array
                     $data['message'] = $_REQUEST['review'];
                     $data['quality'] = intval($_REQUEST['quality']);
                     $data['incomplete'] = !empty($_REQUEST['incomplete']);
                     $meta[$writeRev][$parid]['reviews'][$user] = $data;
                     # Review applies to latest revision as well
                     if (empty($REV) || $meta['current'][$parid]['changed'] == $writeRev) {
                         $meta['current'][$parid]['reviews'][$user] = $data;
                         io_saveFile(metaFN($ID, '.translate'), serialize($meta['current']));
                     }
                     # Save metadata
                     io_saveFile(metaFN($ID, '.translateHistory'), serialize($meta));
                 }
             }
         }
     }
 }
Esempio n. 2
0
/**
 * Saves a wikitext by calling io_writeWikiPage.
 * Also directs changelog and attic updates.
 *
 * @author Andreas Gohr <*****@*****.**>
 * @author Ben Coburn <*****@*****.**>
 */
function saveWikiText($id, $text, $summary, $minor = false)
{
    /* Note to developers:
         This code is subtle and delicate. Test the behavior of
         the attic and changelog with dokuwiki and external edits
         after any changes. External edits change the wiki page
         directly without using php or dokuwiki.
      */
    global $conf;
    global $lang;
    global $REV;
    // ignore if no changes were made
    if ($text == rawWiki($id, '')) {
        return;
    }
    $file = wikiFN($id);
    $old = @filemtime($file);
    // from page
    $wasRemoved = empty($text);
    $wasCreated = !@file_exists($file);
    $wasReverted = $REV == true;
    $newRev = false;
    $oldRev = getRevisions($id, -1, 1, 1024);
    // from changelog
    $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
    if (!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old >= $oldRev) {
        // add old revision to the attic if missing
        saveOldRevision($id);
        // add a changelog entry if this edit came from outside dokuwiki
        if ($old > $oldRev) {
            addLogEntry($old, $id);
            // send notify mails
            notify($id, 'admin', $oldRev, '', false);
            notify($id, 'subscribers', $oldRev, '', false);
            // remove soon to be stale instructions
            $cache = new cache_instructions($id, $file);
            $cache->removeCache();
        }
    }
    if ($wasRemoved) {
        // pre-save deleted revision
        @touch($file);
        clearstatcache();
        $newRev = saveOldRevision($id);
        // remove empty file
        @unlink($file);
        // remove old meta info...
        $mfiles = metaFiles($id);
        $changelog = metaFN($id, '.changes');
        foreach ($mfiles as $mfile) {
            // but keep per-page changelog to preserve page history
            if (@file_exists($mfile) && $mfile !== $changelog) {
                @unlink($mfile);
            }
        }
        $del = true;
        // autoset summary on deletion
        if (empty($summary)) {
            $summary = $lang['deleted'];
        }
        // remove empty namespaces
        io_sweepNS($id, 'datadir');
        io_sweepNS($id, 'mediadir');
    } else {
        // save file (namespace dir is created in io_writeWikiPage)
        io_writeWikiPage($file, $text, $id);
        // pre-save the revision, to keep the attic in sync
        $newRev = saveOldRevision($id);
        $del = false;
    }
    // select changelog line type
    $extra = '';
    $type = 'E';
    if ($wasReverted) {
        $type = 'R';
        $extra = $REV;
    } else {
        if ($wasCreated) {
            $type = 'C';
        } else {
            if ($wasRemoved) {
                $type = 'D';
            } else {
                if ($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) {
                    $type = 'e';
                }
            }
        }
    }
    //minor edits only for logged in users
    addLogEntry($newRev, $id, $type, $summary, $extra);
    // send notify mails
    notify($id, 'admin', $old, $summary, $minor);
    notify($id, 'subscribers', $old, $summary, $minor);
    // update the purgefile (timestamp of the last time anything within the wiki was changed)
    io_saveFile($conf['cachedir'] . '/purgefile', time());
}
Esempio n. 3
0
/**
 * Saves a wikitext by calling io_writeWikiPage.
 * Also directs changelog and attic updates.
 *
 * @author Andreas Gohr <*****@*****.**>
 * @author Ben Coburn <*****@*****.**>
 */
function saveWikiText($id, $text, $summary, $minor = false)
{
    /* Note to developers:
         This code is subtle and delicate. Test the behavior of
         the attic and changelog with dokuwiki and external edits
         after any changes. External edits change the wiki page
         directly without using php or dokuwiki.
       */
    global $conf;
    global $lang;
    global $REV;
    // ignore if no changes were made
    if ($text == rawWiki($id, '')) {
        return;
    }
    $file = wikiFN($id);
    $old = @filemtime($file);
    // from page
    $wasRemoved = empty($text);
    $wasCreated = !@file_exists($file);
    $wasReverted = $REV == true;
    $newRev = false;
    $oldRev = getRevisions($id, -1, 1, 1024);
    // from changelog
    $oldRev = (int) (empty($oldRev) ? 0 : $oldRev[0]);
    if (!@file_exists(wikiFN($id, $old)) && @file_exists($file) && $old >= $oldRev) {
        // add old revision to the attic if missing
        saveOldRevision($id);
        // add a changelog entry if this edit came from outside dokuwiki
        if ($old > $oldRev) {
            addLogEntry($old, $id, DOKU_CHANGE_TYPE_EDIT, $lang['external_edit'], '', array('ExternalEdit' => true));
            // remove soon to be stale instructions
            $cache = new cache_instructions($id, $file);
            $cache->removeCache();
        }
    }
    if ($wasRemoved) {
        // Send "update" event with empty data, so plugins can react to page deletion
        $data = array(array($file, '', false), getNS($id), noNS($id), false);
        trigger_event('IO_WIKIPAGE_WRITE', $data);
        // pre-save deleted revision
        @touch($file);
        clearstatcache();
        $newRev = saveOldRevision($id);
        // remove empty file
        @unlink($file);
        // remove old meta info...
        $mfiles = metaFiles($id);
        $changelog = metaFN($id, '.changes');
        $metadata = metaFN($id, '.meta');
        $subscribers = metaFN($id, '.mlist');
        foreach ($mfiles as $mfile) {
            // but keep per-page changelog to preserve page history, keep subscriber list and keep meta data
            if (@file_exists($mfile) && $mfile !== $changelog && $mfile !== $metadata && $mfile !== $subscribers) {
                @unlink($mfile);
            }
        }
        // purge meta data
        p_purge_metadata($id);
        $del = true;
        // autoset summary on deletion
        if (empty($summary)) {
            $summary = $lang['deleted'];
        }
        // remove empty namespaces
        io_sweepNS($id, 'datadir');
        io_sweepNS($id, 'mediadir');
    } else {
        // save file (namespace dir is created in io_writeWikiPage)
        io_writeWikiPage($file, $text, $id);
        // pre-save the revision, to keep the attic in sync
        $newRev = saveOldRevision($id);
        $del = false;
    }
    // select changelog line type
    $extra = '';
    $type = DOKU_CHANGE_TYPE_EDIT;
    if ($wasReverted) {
        $type = DOKU_CHANGE_TYPE_REVERT;
        $extra = $REV;
    } else {
        if ($wasCreated) {
            $type = DOKU_CHANGE_TYPE_CREATE;
        } else {
            if ($wasRemoved) {
                $type = DOKU_CHANGE_TYPE_DELETE;
            } else {
                if ($minor && $conf['useacl'] && $_SERVER['REMOTE_USER']) {
                    $type = DOKU_CHANGE_TYPE_MINOR_EDIT;
                }
            }
        }
    }
    //minor edits only for logged in users
    addLogEntry($newRev, $id, $type, $summary, $extra);
    // send notify mails
    notify($id, 'admin', $old, $summary, $minor);
    notify($id, 'subscribers', $old, $summary, $minor);
    // update the purgefile (timestamp of the last time anything within the wiki was changed)
    io_saveFile($conf['cachedir'] . '/purgefile', time());
    // if useheading is enabled, purge the cache of all linking pages
    if (useHeading('content')) {
        $pages = ft_backlinks($id);
        foreach ($pages as $page) {
            $cache = new cache_renderer($page, wikiFN($page), 'xhtml');
            $cache->removeCache();
        }
    }
}