1007225e5Sgerardnico<?php 2007225e5Sgerardnico 337748cd8SNickeaurequire_once(__DIR__ . '/../ComboStrap/PluginUtility.php'); 4c3437056SNickeau 5c3437056SNickeauuse ComboStrap\Alias; 6c3437056SNickeauuse ComboStrap\Aliases; 7c3437056SNickeauuse ComboStrap\DatabasePageRow; 8c3437056SNickeauuse ComboStrap\ExceptionComboRuntime; 9c3437056SNickeauuse ComboStrap\File; 10*4cadd4f8SNickeauuse ComboStrap\FileSystems; 11*4cadd4f8SNickeauuse ComboStrap\MarkupRef; 12c3437056SNickeauuse ComboStrap\LogUtility; 13c3437056SNickeauuse ComboStrap\MetadataDbStore; 14c3437056SNickeauuse ComboStrap\MetadataDokuWikiStore; 15c3437056SNickeauuse ComboStrap\Page; 16c3437056SNickeauuse ComboStrap\PageId; 17c3437056SNickeauuse ComboStrap\PluginUtility; 18c3437056SNickeauuse ComboStrap\Site; 19c3437056SNickeau 20007225e5Sgerardnico 21007225e5Sgerardnico/** 22007225e5Sgerardnico * Class action_plugin_combo_move 23c3437056SNickeau * Handle the move of a page in order to update: 24c3437056SNickeau * * the link 25c3437056SNickeau * * the data in the database 26007225e5Sgerardnico */ 27007225e5Sgerardnicoclass action_plugin_combo_linkmove extends DokuWiki_Action_Plugin 28007225e5Sgerardnico{ 29007225e5Sgerardnico 30c3437056SNickeau 31c3437056SNickeau const CANONICAL = "move"; 32c3437056SNickeau 33c3437056SNickeau private static function checkAndSendAMessageIfLockFilePresent(): bool 34c3437056SNickeau { 35*4cadd4f8SNickeau $lockFile = Site::getDataDirectory()->resolve("locks_plugin_move.lock"); 36*4cadd4f8SNickeau if (!FileSystems::exists($lockFile)) { 37c3437056SNickeau return false; 38c3437056SNickeau } 39*4cadd4f8SNickeau $lockFileDateTimeModified = FileSystems::getModifiedTime($lockFile); 40c3437056SNickeau $lockFileModifiedTimestamp = $lockFileDateTimeModified->getTimestamp(); 41c3437056SNickeau $now = time(); 42c3437056SNickeau 43c3437056SNickeau $distance = $now - $lockFileModifiedTimestamp; 44c3437056SNickeau $lockFileAgeInMinute = ($distance) / 60; 45c3437056SNickeau if ($lockFileAgeInMinute > 5) { 46c3437056SNickeau LogUtility::msg("The move lockfile ($lockFile) exists and is older than 5 minutes (exactly $lockFileAgeInMinute minutes). If you are no more in a move, you should delete this file otherwise it will disable the move of page and the cache."); 47c3437056SNickeau return true; 48c3437056SNickeau } 49c3437056SNickeau return false; 50c3437056SNickeau } 51c3437056SNickeau 52007225e5Sgerardnico /** 53531e725cSNickeau * As explained https://www.dokuwiki.org/plugin:move#support_for_other_plugins 54007225e5Sgerardnico * @param Doku_Event_Handler $controller 55007225e5Sgerardnico */ 56007225e5Sgerardnico function register(Doku_Event_Handler $controller) 57007225e5Sgerardnico { 58c3437056SNickeau 59c3437056SNickeau /** 60c3437056SNickeau * To rewrite the page meta in the database 61c3437056SNickeau */ 62c3437056SNickeau $controller->register_hook('PLUGIN_MOVE_PAGE_RENAME', 'BEFORE', $this, 'handle_rename_before', array()); 63c3437056SNickeau $controller->register_hook('PLUGIN_MOVE_PAGE_RENAME', 'AFTER', $this, 'handle_rename_after', array()); 64c3437056SNickeau 65c3437056SNickeau /** 66c3437056SNickeau * To rewrite the link 67c3437056SNickeau */ 68c3437056SNickeau $controller->register_hook('PLUGIN_MOVE_HANDLERS_REGISTER', 'BEFORE', $this, 'handle_link', array()); 69c3437056SNickeau 70c3437056SNickeau 71c3437056SNickeau /** 72c3437056SNickeau * Check for the presence of a lock file 73c3437056SNickeau */ 74c3437056SNickeau $controller->register_hook('PARSER_WIKITEXT_PREPROCESS', 'BEFORE', $this, 'check_lock_file_age', array()); 75c3437056SNickeau 76c3437056SNickeau 77007225e5Sgerardnico } 78007225e5Sgerardnico 79007225e5Sgerardnico /** 80c3437056SNickeau * @param Doku_Event $event 81c3437056SNickeau * @param $params 82c3437056SNickeau * 83c3437056SNickeau * When a lock file is present, 84c3437056SNickeau * the move plugin will purge the data in {@link action_plugin_move_rewrite::handle_cache()} 85c3437056SNickeau * making the rendering fucking slow 86c3437056SNickeau * We check that the lock file is not 87c3437056SNickeau */ 88c3437056SNickeau function check_lock_file_age(Doku_Event $event, $params) 89c3437056SNickeau { 90c3437056SNickeau self::checkAndSendAMessageIfLockFilePresent(); 91c3437056SNickeau 92c3437056SNickeau } 93c3437056SNickeau 94c3437056SNickeau /** 95c3437056SNickeau * Handle the path modification of a page 96c3437056SNickeau * @param Doku_Event $event - https://www.dokuwiki.org/plugin:move#for_plugin_authors 97c3437056SNickeau * @param $params 98c3437056SNickeau * 99c3437056SNickeau */ 100c3437056SNickeau function handle_rename_before(Doku_Event $event, $params) 101c3437056SNickeau { 102c3437056SNickeau /** 103c3437056SNickeau * Check that the lock file is not older 104c3437056SNickeau * Lock file bigger than 5 minutes 105c3437056SNickeau * Is not really possible 106c3437056SNickeau */ 107c3437056SNickeau $result = self::checkAndSendAMessageIfLockFilePresent(); 108c3437056SNickeau if ($result === true) { 109c3437056SNickeau $event->preventDefault(); 110c3437056SNickeau LogUtility::msg("The move lock file is present, the move was canceled."); 111c3437056SNickeau } 112c3437056SNickeau 113c3437056SNickeau } 114c3437056SNickeau 115c3437056SNickeau /** 116c3437056SNickeau * Handle the path modification of a page after 117c3437056SNickeau * 118c3437056SNickeau * The metadata file should also have been moved 119c3437056SNickeau * 120c3437056SNickeau * @param Doku_Event $event - https://www.dokuwiki.org/plugin:move#for_plugin_authors 121c3437056SNickeau * @param $params 122c3437056SNickeau * 123c3437056SNickeau */ 124c3437056SNickeau function handle_rename_after(Doku_Event $event, $params) 125c3437056SNickeau { 126c3437056SNickeau /** 127c3437056SNickeau * 128c3437056SNickeau * $event->data 129c3437056SNickeau * src_id ⇒ string – the original ID of the page 130c3437056SNickeau * dst_id ⇒ string – the new ID of the page 131c3437056SNickeau */ 132c3437056SNickeau $sourceId = $event->data["src_id"]; 133c3437056SNickeau $targetId = $event->data["dst_id"]; 134c3437056SNickeau try { 135c3437056SNickeau 136c3437056SNickeau /** 137c3437056SNickeau * Update the dokuwiki id and path 138c3437056SNickeau */ 139c3437056SNickeau $databasePage = DatabasePageRow::createFromDokuWikiId($sourceId); 140c3437056SNickeau if (!$databasePage->exists()) { 141c3437056SNickeau return; 142c3437056SNickeau } 143c3437056SNickeau $databasePage->updatePathAndDokuwikiId($targetId); 144c3437056SNickeau 145c3437056SNickeau /** 146c3437056SNickeau * Check page id 147c3437056SNickeau */ 148c3437056SNickeau $targetPage = Page::createPageFromId($targetId); 149c3437056SNickeau $targetPageId = PageId::createForPage($targetPage); 150c3437056SNickeau $targetPageIdValue = $targetPageId->getValueFromStore(); 151c3437056SNickeau $databasePageIdValue = $databasePage->getPageId(); 152c3437056SNickeau 153c3437056SNickeau if ($databasePageIdValue !== $targetPageIdValue) { 154c3437056SNickeau // this should never happened in test/dev 155c3437056SNickeau $targetPageId->setValueForce($targetPageIdValue); 156c3437056SNickeau } 157c3437056SNickeau 158c3437056SNickeau /** 159c3437056SNickeau * Add the alias 160c3437056SNickeau */ 161c3437056SNickeau Aliases::createForPage($targetPage) 162c3437056SNickeau ->addAlias($sourceId) 163c3437056SNickeau ->setWriteStore(MetadataDokuWikiStore::class) 164c3437056SNickeau ->sendToWriteStore() 165c3437056SNickeau ->persist() 166c3437056SNickeau ->setReadStore(MetadataDbStore::class) 167c3437056SNickeau ->sendToWriteStore() 168c3437056SNickeau ->persist(); 169c3437056SNickeau 170c3437056SNickeau 171c3437056SNickeau } catch (Exception $exception) { 172c3437056SNickeau // We catch the errors if any to not stop the move 173c3437056SNickeau // There is no transaction feature (it happens or not) 174c3437056SNickeau $message = "An error occurred during the move replication to the database. Error message was: " . $exception->getMessage(); 175c3437056SNickeau if (PluginUtility::isDevOrTest()) { 176c3437056SNickeau throw new RuntimeException($exception); 177c3437056SNickeau } else { 178c3437056SNickeau LogUtility::msg($message, LogUtility::LVL_MSG_ERROR, self::CANONICAL); 179c3437056SNickeau } 180c3437056SNickeau } 181c3437056SNickeau 182c3437056SNickeau } 183c3437056SNickeau 184c3437056SNickeau 185c3437056SNickeau /** 186007225e5Sgerardnico * Handle the move of a page 187007225e5Sgerardnico * @param Doku_Event $event 188007225e5Sgerardnico * @param $params 189007225e5Sgerardnico */ 190c3437056SNickeau function handle_link(Doku_Event $event, $params) 191007225e5Sgerardnico { 192007225e5Sgerardnico /** 193ef295d81Sgerardnico * The handlers is the name of the component (ie refers to the {@link syntax_plugin_combo_link} handler) 194ef295d81Sgerardnico * and 'rewrite_combo' to the below method 195007225e5Sgerardnico */ 196ef295d81Sgerardnico $event->data['handlers'][syntax_plugin_combo_link::COMPONENT] = array($this, 'rewrite_combo'); 197007225e5Sgerardnico } 198007225e5Sgerardnico 199007225e5Sgerardnico /** 200007225e5Sgerardnico * 201007225e5Sgerardnico * @param $match 202007225e5Sgerardnico * @param $state 203007225e5Sgerardnico * @param $pos 204007225e5Sgerardnico * @param $plugin 205007225e5Sgerardnico * @param helper_plugin_move_handler $handler 206007225e5Sgerardnico */ 207007225e5Sgerardnico public function rewrite_combo($match, $state, $pos, $plugin, helper_plugin_move_handler $handler) 208007225e5Sgerardnico { 209007225e5Sgerardnico /** 2105f891b7eSNickeau * The original move method 2115f891b7eSNickeau * is {@link helper_plugin_move_handler::internallink()} 2125f891b7eSNickeau * 213007225e5Sgerardnico */ 2145f891b7eSNickeau if ($state == DOKU_LEXER_ENTER) { 215*4cadd4f8SNickeau $ref = syntax_plugin_combo_link::parse($match)[syntax_plugin_combo_link::ATTRIBUTE_HREF]; 216*4cadd4f8SNickeau $link = new MarkupRef($ref); 217*4cadd4f8SNickeau if ($link->getUriType() == MarkupRef::WIKI_URI) { 218007225e5Sgerardnico 2195f891b7eSNickeau $handler->internallink($match, $state, $pos); 2205f891b7eSNickeau $suffix = "]]"; 22121913ab3SNickeau if (substr($handler->calls, -strlen($suffix)) == $suffix) { 22221913ab3SNickeau $handler->calls = substr($handler->calls, 0, strlen($handler->calls) - strlen($suffix)); 2235f891b7eSNickeau } 2245f891b7eSNickeau 2255f891b7eSNickeau } else { 2265f891b7eSNickeau 2275f891b7eSNickeau // Other type of links 2285f891b7eSNickeau $handler->calls .= $match; 2295f891b7eSNickeau 2305f891b7eSNickeau } 2315f891b7eSNickeau } else { 2325f891b7eSNickeau 2335f891b7eSNickeau // Description and ending 2345f891b7eSNickeau $handler->calls .= $match; 2355f891b7eSNickeau 2365f891b7eSNickeau } 237007225e5Sgerardnico } 238007225e5Sgerardnico 239007225e5Sgerardnico 240007225e5Sgerardnico} 241