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