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