xref: /dokuwiki/inc/Draft.php (revision 0aabe6f83fad7d8ce23367ad642b6979fc65b4f0)
1<?php
2
3namespace dokuwiki;
4
5/**
6 * Class Draft
7 *
8 * @package dokuwiki
9 */
10class Draft
11{
12
13    protected $errors = [];
14    protected $cname;
15    protected $id;
16    protected $client;
17
18    public function __construct($ID, $client)
19    {
20        $this->id = $ID;
21        $this->client = $client;
22        $this->cname = getCacheName($client.$ID, '.draft');
23        if(file_exists($this->cname) && file_exists(wikiFN($ID))) {
24            if (filemtime($this->cname) < filemtime(wikiFN($ID))) {
25                // remove stale draft
26                $this->deleteDraft();
27            }
28        }
29    }
30
31    /**
32     * Get the filename for this draft (whether or not it exists)
33     *
34     * @return string
35     */
36    public function getDraftFilename()
37    {
38        return $this->cname;
39    }
40
41    /**
42     * Checks if this draft exists on the filesystem
43     *
44     * @return bool
45     */
46    public function isDraftAvailable()
47    {
48        return file_exists($this->cname);
49    }
50
51    /**
52     * Save a draft of a current edit session
53     *
54     * The draft will not be saved if
55     *   - drafts are deactivated in the config
56     *   - or the editarea is empty and there are no event handlers registered
57     *   - or the event is prevented
58     *
59     * @triggers DRAFT_SAVE
60     *
61     * @return bool whether has the draft been saved
62     */
63    public function saveDraft()
64    {
65        global $INPUT, $INFO, $EVENT_HANDLER, $conf;
66        if (!$conf['usedraft']) {
67            return false;
68        }
69        if (!$INPUT->post->has('wikitext') &&
70            !$EVENT_HANDLER->hasHandlerForEvent('DRAFT_SAVE')) {
71            return false;
72        }
73        $draft = [
74            'id' => $this->id,
75            'prefix' => substr($INPUT->post->str('prefix'), 0, -1),
76            'text' => $INPUT->post->str('wikitext'),
77            'suffix' => $INPUT->post->str('suffix'),
78            'date' => $INPUT->post->int('date'),
79            'client' => $this->client,
80            'cname' => $this->cname,
81            'errors' => [],
82        ];
83        $event = new \Doku_Event('DRAFT_SAVE', $draft);
84        if ($event->advise_before()) {
85            $draft['hasBeenSaved'] = io_saveFile($draft['cname'], serialize($draft));
86            if ($draft['hasBeenSaved']) {
87                $INFO['draft'] = $draft['cname'];
88            }
89        } else {
90            $draft['hasBeenSaved'] = false;
91        }
92        $event->advise_after();
93
94        $this->errors = $draft['errors'];
95
96        return $draft['hasBeenSaved'];
97    }
98
99    /**
100     * Get the text from the draft file
101     *
102     * @throws \RuntimeException if the draft file doesn't exist
103     *
104     * @return string
105     */
106    public function getDraftText()
107    {
108        if (!file_exists($this->cname)) {
109            throw new \RuntimeException(
110                "Draft for page $this->id and user $this->client doesn't exist at $this->cname."
111            );
112        }
113        $draft = unserialize(io_readFile($this->cname,false));
114        return cleanText(con($draft['prefix'],$draft['text'],$draft['suffix'],true));
115    }
116
117    /**
118     * Remove the draft from the filesystem
119     *
120     * Also sets $INFO['draft'] to null
121     */
122    public function deleteDraft()
123    {
124        global $INFO;
125        @unlink($this->cname);
126        $INFO['draft'] = null;
127    }
128
129    /**
130     * Get a formatted message stating when the draft was saved
131     *
132     * @return string
133     */
134    public function getDraftMessage()
135    {
136        global $lang;
137        return $lang['draftdate'] . ' ' . dformat(filemtime($this->cname));
138    }
139
140    /**
141     * Retrieve the errors that occured when saving the draft
142     *
143     * @return array
144     */
145    public function getErrors()
146    {
147        return $this->errors;
148    }
149}
150