xref: /dokuwiki/inc/Draft.php (revision d4f83172d9533c4d84f450fe22ef630816b21d75)
10aabe6f8SMichael Große<?php
20aabe6f8SMichael Große
30aabe6f8SMichael Großenamespace dokuwiki;
40aabe6f8SMichael Große
524870174SAndreas Gohruse dokuwiki\Extension\Event;
6*d4f83172SAndreas Gohr
70aabe6f8SMichael Große/**
80aabe6f8SMichael Große * Class Draft
90aabe6f8SMichael Große *
100aabe6f8SMichael Große * @package dokuwiki
110aabe6f8SMichael Große */
120aabe6f8SMichael Großeclass Draft
130aabe6f8SMichael Große{
140aabe6f8SMichael Große    protected $errors = [];
150aabe6f8SMichael Große    protected $cname;
160aabe6f8SMichael Große    protected $id;
170aabe6f8SMichael Große    protected $client;
180aabe6f8SMichael Große
19e432cc89SMichael Große    /**
20e432cc89SMichael Große     * Draft constructor.
21e432cc89SMichael Große     *
22e432cc89SMichael Große     * @param string $ID the page id for this draft
23e432cc89SMichael Große     * @param string $client the client identification (username or ip or similar) for this draft
24e432cc89SMichael Große     */
250aabe6f8SMichael Große    public function __construct($ID, $client)
260aabe6f8SMichael Große    {
270aabe6f8SMichael Große        $this->id = $ID;
280aabe6f8SMichael Große        $this->client = $client;
2924201594SAndreas Gohr        $this->cname = getCacheName("$client\n$ID", '.draft');
300aabe6f8SMichael Große        if (file_exists($this->cname) && file_exists(wikiFN($ID))) {
310aabe6f8SMichael Große            if (filemtime($this->cname) < filemtime(wikiFN($ID))) {
320aabe6f8SMichael Große                // remove stale draft
330aabe6f8SMichael Große                $this->deleteDraft();
340aabe6f8SMichael Große            }
350aabe6f8SMichael Große        }
360aabe6f8SMichael Große    }
370aabe6f8SMichael Große
380aabe6f8SMichael Große    /**
390aabe6f8SMichael Große     * Get the filename for this draft (whether or not it exists)
400aabe6f8SMichael Große     *
410aabe6f8SMichael Große     * @return string
420aabe6f8SMichael Große     */
430aabe6f8SMichael Große    public function getDraftFilename()
440aabe6f8SMichael Große    {
450aabe6f8SMichael Große        return $this->cname;
460aabe6f8SMichael Große    }
470aabe6f8SMichael Große
480aabe6f8SMichael Große    /**
490aabe6f8SMichael Große     * Checks if this draft exists on the filesystem
500aabe6f8SMichael Große     *
510aabe6f8SMichael Große     * @return bool
520aabe6f8SMichael Große     */
530aabe6f8SMichael Große    public function isDraftAvailable()
540aabe6f8SMichael Große    {
550aabe6f8SMichael Große        return file_exists($this->cname);
560aabe6f8SMichael Große    }
570aabe6f8SMichael Große
580aabe6f8SMichael Große    /**
590aabe6f8SMichael Große     * Save a draft of a current edit session
600aabe6f8SMichael Große     *
610aabe6f8SMichael Große     * The draft will not be saved if
620aabe6f8SMichael Große     *   - drafts are deactivated in the config
630aabe6f8SMichael Große     *   - or the editarea is empty and there are no event handlers registered
640aabe6f8SMichael Große     *   - or the event is prevented
650aabe6f8SMichael Große     *
660aabe6f8SMichael Große     * @triggers DRAFT_SAVE
670aabe6f8SMichael Große     *
680aabe6f8SMichael Große     * @return bool whether has the draft been saved
690aabe6f8SMichael Große     */
700aabe6f8SMichael Große    public function saveDraft()
710aabe6f8SMichael Große    {
720aabe6f8SMichael Große        global $INPUT, $INFO, $EVENT_HANDLER, $conf;
730aabe6f8SMichael Große        if (!$conf['usedraft']) {
740aabe6f8SMichael Große            return false;
750aabe6f8SMichael Große        }
767d34963bSAndreas Gohr        if (
777d34963bSAndreas Gohr            !$INPUT->post->has('wikitext') &&
787d34963bSAndreas Gohr            !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE')
797d34963bSAndreas Gohr        ) {
800aabe6f8SMichael Große            return false;
810aabe6f8SMichael Große        }
820aabe6f8SMichael Große        $draft = [
830aabe6f8SMichael Große            'id' => $this->id,
840aabe6f8SMichael Große            'prefix' => substr($INPUT->post->str('prefix'), 0, -1),
850aabe6f8SMichael Große            'text' => $INPUT->post->str('wikitext'),
860aabe6f8SMichael Große            'suffix' => $INPUT->post->str('suffix'),
870aabe6f8SMichael Große            'date' => $INPUT->post->int('date'),
880aabe6f8SMichael Große            'client' => $this->client,
890aabe6f8SMichael Große            'cname' => $this->cname,
900aabe6f8SMichael Große            'errors' => [],
910aabe6f8SMichael Große        ];
9224870174SAndreas Gohr        $event = new Event('DRAFT_SAVE', $draft);
930aabe6f8SMichael Große        if ($event->advise_before()) {
940aabe6f8SMichael Große            $draft['hasBeenSaved'] = io_saveFile($draft['cname'], serialize($draft));
950aabe6f8SMichael Große            if ($draft['hasBeenSaved']) {
960aabe6f8SMichael Große                $INFO['draft'] = $draft['cname'];
970aabe6f8SMichael Große            }
980aabe6f8SMichael Große        } else {
990aabe6f8SMichael Große            $draft['hasBeenSaved'] = false;
1000aabe6f8SMichael Große        }
1010aabe6f8SMichael Große        $event->advise_after();
1020aabe6f8SMichael Große
1030aabe6f8SMichael Große        $this->errors = $draft['errors'];
1040aabe6f8SMichael Große
1050aabe6f8SMichael Große        return $draft['hasBeenSaved'];
1060aabe6f8SMichael Große    }
1070aabe6f8SMichael Große
1080aabe6f8SMichael Große    /**
1090aabe6f8SMichael Große     * Get the text from the draft file
1100aabe6f8SMichael Große     *
1110aabe6f8SMichael Große     * @throws \RuntimeException if the draft file doesn't exist
1120aabe6f8SMichael Große     *
1130aabe6f8SMichael Große     * @return string
1140aabe6f8SMichael Große     */
1150aabe6f8SMichael Große    public function getDraftText()
1160aabe6f8SMichael Große    {
1170aabe6f8SMichael Große        if (!file_exists($this->cname)) {
1180aabe6f8SMichael Große            throw new \RuntimeException(
1190aabe6f8SMichael Große                "Draft for page $this->id and user $this->client doesn't exist at $this->cname."
1200aabe6f8SMichael Große            );
1210aabe6f8SMichael Große        }
1220aabe6f8SMichael Große        $draft = unserialize(io_readFile($this->cname, false));
1230aabe6f8SMichael Große        return cleanText(con($draft['prefix'], $draft['text'], $draft['suffix'], true));
1240aabe6f8SMichael Große    }
1250aabe6f8SMichael Große
1260aabe6f8SMichael Große    /**
1270aabe6f8SMichael Große     * Remove the draft from the filesystem
1280aabe6f8SMichael Große     *
1290aabe6f8SMichael Große     * Also sets $INFO['draft'] to null
1300aabe6f8SMichael Große     */
1310aabe6f8SMichael Große    public function deleteDraft()
1320aabe6f8SMichael Große    {
1330aabe6f8SMichael Große        global $INFO;
1340aabe6f8SMichael Große        @unlink($this->cname);
1350aabe6f8SMichael Große        $INFO['draft'] = null;
1360aabe6f8SMichael Große    }
1370aabe6f8SMichael Große
1380aabe6f8SMichael Große    /**
1390aabe6f8SMichael Große     * Get a formatted message stating when the draft was saved
1400aabe6f8SMichael Große     *
1410aabe6f8SMichael Große     * @return string
1420aabe6f8SMichael Große     */
1430aabe6f8SMichael Große    public function getDraftMessage()
1440aabe6f8SMichael Große    {
1450aabe6f8SMichael Große        global $lang;
1460aabe6f8SMichael Große        return $lang['draftdate'] . ' ' . dformat(filemtime($this->cname));
1470aabe6f8SMichael Große    }
1480aabe6f8SMichael Große
1490aabe6f8SMichael Große    /**
1500aabe6f8SMichael Große     * Retrieve the errors that occured when saving the draft
1510aabe6f8SMichael Große     *
1520aabe6f8SMichael Große     * @return array
1530aabe6f8SMichael Große     */
1540aabe6f8SMichael Große    public function getErrors()
1550aabe6f8SMichael Große    {
1560aabe6f8SMichael Große        return $this->errors;
1570aabe6f8SMichael Große    }
158520438b3SMichael Große
159520438b3SMichael Große    /**
160520438b3SMichael Große     * Get the timestamp when this draft was saved
161520438b3SMichael Große     *
162520438b3SMichael Große     * @return int
163520438b3SMichael Große     */
164520438b3SMichael Große    public function getDraftDate()
165520438b3SMichael Große    {
166520438b3SMichael Große        return filemtime($this->cname);
167520438b3SMichael Große    }
1680aabe6f8SMichael Große}
169