1<?php 2 3use ComboStrap\ComboFs; 4use ComboStrap\DatabasePageRow; 5use ComboStrap\Event; 6use ComboStrap\ExceptionCompile; 7use ComboStrap\ExceptionNotFound; 8use ComboStrap\ExecutionContext; 9use ComboStrap\FileSystems; 10use ComboStrap\LocalPath; 11use ComboStrap\LogUtility; 12use ComboStrap\MarkupCacheDependencies; 13use ComboStrap\MarkupPath; 14use ComboStrap\PageId; 15use ComboStrap\PagePath; 16use ComboStrap\Site; 17use ComboStrap\SlotSystem; 18 19 20require_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 21 22/** 23 * When a page is added or deleted from the file system 24 */ 25class action_plugin_combo_pagesystemmutation extends DokuWiki_Action_Plugin 26{ 27 28 29 public const PAGE_SYSTEM_MUTATION_EVENT_NAME = 'page_system_mutation'; 30 31 const TYPE_ATTRIBUTE = "type"; 32 const TYPE_CREATION = "creation"; 33 const TYPE_DELETION = "deletion"; 34 const CANONICAL = "combo-file-system"; 35 36 37 public function register(Doku_Event_Handler $controller) 38 { 39 40 41 /** 42 * 43 * And To delete sidebar (cache) cache when a page was modified in a namespace 44 * https://combostrap.com/sideslots 45 */ 46 $controller->register_hook('IO_WIKIPAGE_WRITE', 'BEFORE', $this, 'createFileSystemMutation', array()); 47 48 /** 49 * Synchronization with the combo file system 50 */ 51 $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'AFTER', $this, 'comboFsSynchronization', array()); 52 53 /** 54 * process the Async event 55 */ 56 $controller->register_hook(self::PAGE_SYSTEM_MUTATION_EVENT_NAME, 'AFTER', $this, 'handleFileSystemMutation'); 57 58 } 59 60 /** 61 * @param $event 62 * @throws Exception 63 * @link https://www.dokuwiki.org/devel:event:io_wikipage_write 64 * 65 * On update to an existing page this event is called twice, once for the transfer of the old version to the attic 66 * (rev will have a value) 67 * and once to write the new version of the page into the wiki (rev is false) 68 */ 69 function createFileSystemMutation($event) 70 { 71 72 $data = $event->data; 73 $pageName = $data[2]; 74 75 /** 76 * Modification to the secondary slot are not processed 77 */ 78 if (in_array($pageName, SlotSystem::getSlotNames())) return; 79 80 81 /** 82 * TODO ?: the common uses the common_wikipage_save instead ? 83 * https://www.dokuwiki.org/devel:event:common_wikipage_save 84 * File creation 85 * 86 * ``` 87 * Page creation may be detected by checking if the file already exists and the revision is false. 88 * ``` 89 * From https://www.dokuwiki.org/devel:event:io_wikipage_write 90 * 91 */ 92 $rev = $data[3]; 93 $filePath = $data[0][0]; 94 $file = LocalPath::createFromPathString($filePath); 95 if (!FileSystems::exists($file) && $rev === false) { 96 Event::createEvent( 97 action_plugin_combo_pagesystemmutation::PAGE_SYSTEM_MUTATION_EVENT_NAME, 98 [ 99 self::TYPE_ATTRIBUTE => self::TYPE_CREATION, 100 PagePath::getPersistentName() => $file->toWikiPath()->toAbsoluteId() 101 ] 102 ); 103 return; 104 } 105 106 /** 107 * File deletion 108 * (No content) 109 * 110 * ``` 111 * Page deletion may be detected by checking for empty page content. 112 * On update to an existing page this event is called twice, once for the transfer 113 * of the old version to the attic (rev will have a value) 114 * and once to write the new version of the page into the wiki (rev is false) 115 * ``` 116 * From https://www.dokuwiki.org/devel:event:io_wikipage_write 117 */ 118 $append = $data[0][2]; 119 if (!$append) { 120 121 $content = $data[0][1]; 122 if (empty($content) && $rev === false) { 123 // Deletion 124 Event::createEvent( 125 action_plugin_combo_pagesystemmutation::PAGE_SYSTEM_MUTATION_EVENT_NAME, 126 [ 127 self::TYPE_ATTRIBUTE => self::TYPE_DELETION, 128 PagePath::getPersistentName() => $file->toWikiPath()->toAbsoluteId() 129 ] 130 ); 131 } 132 } 133 134 } 135 136 public function handleFileSystemMutation($event) 137 { 138 139 /** 140 * We need to re-render the slot 141 * that are {@link \ComboStrap\MarkupCacheDependencies::PAGE_SYSTEM_DEPENDENCY} 142 * dependent 143 */ 144 $data = $event->data; 145 146 /** 147 * Re-render 148 */ 149 $pathAddedOrDeleted = $data[PagePath::getPersistentName()]; 150 MarkupCacheDependencies::reRenderSideSlotIfNeeded( 151 $pathAddedOrDeleted, 152 MarkupCacheDependencies::PAGE_SYSTEM_DEPENDENCY, 153 self::PAGE_SYSTEM_MUTATION_EVENT_NAME 154 ); 155 156 } 157 158 /** 159 * Store into the Combo file system 160 * @param $event 161 * @return void 162 */ 163 public function comboFsSynchronization($event) 164 { 165 166 $id = $event->data['id']; 167 $markup = MarkupPath::createMarkupFromId($id); 168 169 $changedType = $event->data['changeType']; 170 switch ($changedType) { 171 // creation 172 case DOKU_CHANGE_TYPE_CREATE: 173 /** 174 * For now, we just sync the page id in the index tables (pages) 175 * 176 * This is mandatory to allow permanent url redirection {@link PageUrlType}) 177 */ 178 if (action_plugin_combo_linkmove::isMoveOperation()) { 179 /** 180 * Is this a creation from a move ? 181 */ 182 return; 183 } 184 try { 185 PageId::createForPage($markup) 186 ->getValue(); 187 } catch (ExceptionNotFound $e) { 188 ComboFs::createIfNotExists($markup); 189 } 190 return; 191 case DOKU_CHANGE_TYPE_DELETE: 192 /** 193 * Is this a delete from a move ? 194 */ 195 if (action_plugin_combo_linkmove::isMoveOperation()) { 196 return; 197 } 198 ComboFs::delete($markup); 199 return; 200 } 201 202 203 } 204 205} 206 207 208 209