1007225e5Sgerardnico<?php 2007225e5Sgerardnico/** 3007225e5Sgerardnico * Copyright (c) 2021. ComboStrap, Inc. and its affiliates. All Rights Reserved. 4007225e5Sgerardnico * 5007225e5Sgerardnico * This source code is licensed under the GPL license found in the 6007225e5Sgerardnico * COPYING file in the root directory of this source tree. 7007225e5Sgerardnico * 8007225e5Sgerardnico * @license GPL 3 (https://www.gnu.org/licenses/gpl-3.0.en.html) 9007225e5Sgerardnico * @author ComboStrap <support@combostrap.com> 10007225e5Sgerardnico * 11007225e5Sgerardnico */ 12007225e5Sgerardnicoif (!defined('DOKU_INC')) die(); 13007225e5Sgerardnico 14*c3437056SNickeauuse ComboStrap\AnalyticsDocument; 15*c3437056SNickeauuse ComboStrap\BacklinkCount; 16*c3437056SNickeauuse ComboStrap\DatabasePageRow; 17*c3437056SNickeauuse ComboStrap\Event; 18*c3437056SNickeauuse ComboStrap\ExceptionCombo; 19*c3437056SNickeauuse ComboStrap\ExceptionComboRuntime; 2037748cd8SNickeauuse ComboStrap\FsWikiUtility; 21*c3437056SNickeauuse ComboStrap\LogUtility; 22*c3437056SNickeauuse ComboStrap\MetadataFrontmatterStore; 2371f916b9Sgerardnicouse ComboStrap\Page; 24*c3437056SNickeauuse ComboStrap\PageH1; 2571f916b9Sgerardnicouse ComboStrap\Sqlite; 26007225e5Sgerardnicouse splitbrain\phpcli\Options; 27007225e5Sgerardnico 28e8b2ff59SNickeau/** 29e8b2ff59SNickeau * All dependency are loaded in plugin utility 30e8b2ff59SNickeau */ 3137748cd8SNickeaurequire_once(__DIR__ . '/ComboStrap/PluginUtility.php'); 32007225e5Sgerardnico 33007225e5Sgerardnico/** 34007225e5Sgerardnico * The memory of the server 128 is not enough 35007225e5Sgerardnico */ 36007225e5Sgerardnicoini_set('memory_limit', '256M'); 37007225e5Sgerardnico 38*c3437056SNickeau 39007225e5Sgerardnico/** 40007225e5Sgerardnico * Class cli_plugin_combo 41007225e5Sgerardnico * 42007225e5Sgerardnico * This is a cli: 43007225e5Sgerardnico * https://www.dokuwiki.org/devel:cli_plugins#example 44007225e5Sgerardnico * 45007225e5Sgerardnico * Usage: 46007225e5Sgerardnico * 47007225e5Sgerardnico * ``` 48007225e5Sgerardnico * docker exec -ti $(CONTAINER) /bin/bash 49*c3437056SNickeau * ``` 50*c3437056SNickeau * ``` 51*c3437056SNickeau * set animal=animal-directory-name 52*c3437056SNickeau * php ./bin/plugin.php combo --help 53007225e5Sgerardnico * ``` 54007225e5Sgerardnico * or via the IDE 55007225e5Sgerardnico * 56007225e5Sgerardnico * 57007225e5Sgerardnico * Example: 58007225e5Sgerardnico * https://www.dokuwiki.org/tips:grapher 59007225e5Sgerardnico * 60007225e5Sgerardnico */ 61007225e5Sgerardnicoclass cli_plugin_combo extends DokuWiki_CLI_Plugin 62007225e5Sgerardnico{ 63*c3437056SNickeau 64*c3437056SNickeau const METADATA_TO_DATABASE = "metadata-to-database"; 6571f916b9Sgerardnico const ANALYTICS = "analytics"; 66*c3437056SNickeau const METADATA_TO_FRONTMATTER = "metadata-to-frontmatter"; 6771f916b9Sgerardnico const SYNC = "sync"; 68*c3437056SNickeau const PLUGINS_TO_UPDATE = "plugins-to-update"; 69*c3437056SNickeau const FORCE_OPTION = 'force'; 70*c3437056SNickeau const PORT_OPTION = 'port'; 71*c3437056SNickeau const HOST_OPTION = 'host'; 72*c3437056SNickeau 73007225e5Sgerardnico 74007225e5Sgerardnico /** 75007225e5Sgerardnico * register options and arguments 76007225e5Sgerardnico * @param Options $options 77007225e5Sgerardnico */ 78007225e5Sgerardnico protected function setup(Options $options) 79007225e5Sgerardnico { 80*c3437056SNickeau $help = <<<EOF 81*c3437056SNickeauComboStrap Administrative Commands 82*c3437056SNickeau 83*c3437056SNickeau 84*c3437056SNickeauExample: 85*c3437056SNickeau * Replicate all pages into the database 86*c3437056SNickeau```bash 87*c3437056SNickeauphp ./bin/plugin.php combo metadata-to-database : 88*c3437056SNickeau# or 89*c3437056SNickeauphp ./bin/plugin.php combo metadata-to-database / 90*c3437056SNickeau``` 91*c3437056SNickeau * Replicate only the page `:namespace:my-page` 92*c3437056SNickeau```bash 93*c3437056SNickeauphp ./bin/plugin.php combo metadata-to-database :namespace:my-page 94*c3437056SNickeau# or 95*c3437056SNickeauphp ./bin/plugin.php combo metadata-to-database /namespace/my-page 96*c3437056SNickeau``` 97*c3437056SNickeau 98*c3437056SNickeauAnimal: If you want to use it for an animal farm, you need to set first the animal directory name in a environment variable 99*c3437056SNickeau```bash 100*c3437056SNickeauset animal=animal-directory-name 101*c3437056SNickeau``` 102*c3437056SNickeau 103*c3437056SNickeauEOF; 104*c3437056SNickeau 105*c3437056SNickeau $options->setHelp($help); 106007225e5Sgerardnico $options->registerOption('version', 'print version', 'v'); 107*c3437056SNickeau $options->registerCommand(self::METADATA_TO_DATABASE, "Replicate the file system metadata into the database"); 108*c3437056SNickeau $options->registerCommand(self::ANALYTICS, "Start the analytics and export optionally the data"); 109*c3437056SNickeau $options->registerCommand(self::PLUGINS_TO_UPDATE, "List the plugins to update"); 110*c3437056SNickeau $options->registerCommand(self::METADATA_TO_FRONTMATTER, "Replicate the file system metadata into the page frontmatter"); 111*c3437056SNickeau $options->registerCommand(self::SYNC, "Delete the non-existing pages in the database"); 112*c3437056SNickeau $options->registerArgument( 113*c3437056SNickeau 'path', 114*c3437056SNickeau "The start path (a page or a directory). For all pages, type the root directory '/'", 115*c3437056SNickeau false 11671f916b9Sgerardnico ); 117007225e5Sgerardnico $options->registerOption( 118007225e5Sgerardnico 'output', 119007225e5Sgerardnico "Optional, where to store the analytical data as csv eg. a filename.", 120*c3437056SNickeau 'o', 121*c3437056SNickeau true 122*c3437056SNickeau ); 123007225e5Sgerardnico $options->registerOption( 124*c3437056SNickeau self::HOST_OPTION, 125*c3437056SNickeau "The http host name of your server. This value is used by dokuwiki in the rendering cache key", 126*c3437056SNickeau null, 127*c3437056SNickeau true, 128*c3437056SNickeau self::METADATA_TO_DATABASE 129*c3437056SNickeau ); 130*c3437056SNickeau $options->registerOption( 131*c3437056SNickeau self::PORT_OPTION, 132*c3437056SNickeau "The http host port of your server. This value is used by dokuwiki in the rendering cache key", 133*c3437056SNickeau null, 134*c3437056SNickeau true, 135*c3437056SNickeau self::METADATA_TO_DATABASE 136*c3437056SNickeau ); 137*c3437056SNickeau $options->registerOption( 138*c3437056SNickeau self::FORCE_OPTION, 139*c3437056SNickeau "Replicate with force", 140*c3437056SNickeau 'f', 141*c3437056SNickeau false, 142*c3437056SNickeau self::METADATA_TO_DATABASE 143*c3437056SNickeau ); 14471f916b9Sgerardnico $options->registerOption( 14571f916b9Sgerardnico 'dry', 14671f916b9Sgerardnico "Optional, dry-run", 14771f916b9Sgerardnico 'd', false); 148*c3437056SNickeau 149007225e5Sgerardnico 150007225e5Sgerardnico } 151007225e5Sgerardnico 152007225e5Sgerardnico /** 153007225e5Sgerardnico * The main entry 154007225e5Sgerardnico * @param Options $options 155007225e5Sgerardnico */ 156007225e5Sgerardnico protected function main(Options $options) 157007225e5Sgerardnico { 158007225e5Sgerardnico 159007225e5Sgerardnico 160*c3437056SNickeau $args = $options->getArgs(); 161*c3437056SNickeau 162*c3437056SNickeau 16371f916b9Sgerardnico $depth = $options->getOpt('depth', 0); 16421913ab3SNickeau $cmd = $options->getCmd(); 16521913ab3SNickeau switch ($cmd) { 166*c3437056SNickeau case self::METADATA_TO_DATABASE: 167*c3437056SNickeau $startPath = $this->getStartPath($args); 168*c3437056SNickeau $force = $options->getOpt(self::FORCE_OPTION, false); 169*c3437056SNickeau $hostOptionValue = $options->getOpt(self::HOST_OPTION, null); 170*c3437056SNickeau if ($hostOptionValue === null) { 171*c3437056SNickeau fwrite(STDERR, "The host name is mandatory"); 172*c3437056SNickeau return; 173*c3437056SNickeau } 174*c3437056SNickeau $_SERVER['HTTP_HOST'] = $hostOptionValue; 175*c3437056SNickeau $portOptionName = $options->getOpt(self::PORT_OPTION, null); 176*c3437056SNickeau if ($portOptionName === null) { 177*c3437056SNickeau fwrite(STDERR, "The host port is mandatory"); 178*c3437056SNickeau return; 179*c3437056SNickeau } 180*c3437056SNickeau $_SERVER['SERVER_PORT'] = $portOptionName; 181*c3437056SNickeau $this->index($startPath, $force, $depth); 182*c3437056SNickeau break; 183*c3437056SNickeau case self::METADATA_TO_FRONTMATTER: 184*c3437056SNickeau $startPath = $this->getStartPath($args); 185*c3437056SNickeau $this->frontmatter($startPath, $depth); 186*c3437056SNickeau break; 18771f916b9Sgerardnico case self::ANALYTICS: 188*c3437056SNickeau $startPath = $this->getStartPath($args); 189007225e5Sgerardnico $output = $options->getOpt('output', ''); 190007225e5Sgerardnico //if ($output == '-') $output = 'php://stdout'; 191*c3437056SNickeau $this->analytics($startPath, $output, $depth); 19271f916b9Sgerardnico break; 19371f916b9Sgerardnico case self::SYNC: 194*c3437056SNickeau $this->deleteNonExistingPageFromDatabase(); 195*c3437056SNickeau break; 196*c3437056SNickeau case self::PLUGINS_TO_UPDATE: 197*c3437056SNickeau /** 198*c3437056SNickeau * Endpoint: 199*c3437056SNickeau * self::EXTENSION_REPOSITORY_API.'?fmt=php&ext[]='.urlencode($name) 200*c3437056SNickeau * `http://www.dokuwiki.org/lib/plugins/pluginrepo/api.php?fmt=php&ext[]=`.urlencode($name) 201*c3437056SNickeau */ 202*c3437056SNickeau $pluginList = plugin_list('', true); 203*c3437056SNickeau /* @var helper_plugin_extension_extension $extension */ 204*c3437056SNickeau $extension = $this->loadHelper('extension_extension'); 205*c3437056SNickeau foreach ($pluginList as $name) { 206*c3437056SNickeau $extension->setExtension($name); 207*c3437056SNickeau if ($extension->updateAvailable()) { 208*c3437056SNickeau echo "The extension $name should be updated"; 209*c3437056SNickeau } 210*c3437056SNickeau } 21171f916b9Sgerardnico break; 21271f916b9Sgerardnico default: 213*c3437056SNickeau if ($cmd !== "") { 214*c3437056SNickeau fwrite(STDERR, "Combo: Command unknown (" . $cmd . ")"); 215*c3437056SNickeau } else { 216*c3437056SNickeau echo $options->help(); 217*c3437056SNickeau } 218*c3437056SNickeau exit(1); 21971f916b9Sgerardnico } 220007225e5Sgerardnico 221007225e5Sgerardnico 222007225e5Sgerardnico } 223007225e5Sgerardnico 224007225e5Sgerardnico /** 22571f916b9Sgerardnico * @param array $namespaces 226*c3437056SNickeau * @param bool $rebuild 227007225e5Sgerardnico * @param int $depth recursion depth. 0 for unlimited 228*c3437056SNickeau * @throws ExceptionCombo 229007225e5Sgerardnico */ 230*c3437056SNickeau private function index($namespaces = array(), $rebuild = false, $depth = 0) 231*c3437056SNickeau { 232*c3437056SNickeau 233*c3437056SNickeau /** 234*c3437056SNickeau * Run as admin to overcome the fact that 235*c3437056SNickeau * anonymous user cannot see all links and backlinks 236*c3437056SNickeau */ 237*c3437056SNickeau global $USERINFO; 238*c3437056SNickeau $USERINFO['grps'] = array('admin'); 239*c3437056SNickeau global $INPUT; 240*c3437056SNickeau $INPUT->server->set('REMOTE_USER', "cli"); 241*c3437056SNickeau 242*c3437056SNickeau $pages = FsWikiUtility::getPages($namespaces, $depth); 243*c3437056SNickeau 244*c3437056SNickeau $pageCounter = 0; 245*c3437056SNickeau $totalNumberOfPages = sizeof($pages); 246*c3437056SNickeau while ($pageArray = array_shift($pages)) { 247*c3437056SNickeau $id = $pageArray['id']; 248*c3437056SNickeau /** 249*c3437056SNickeau * Indexing the page start the database replication 250*c3437056SNickeau * See {@link action_plugin_combo_fulldatabasereplication} 251*c3437056SNickeau */ 252*c3437056SNickeau $pageCounter++; 253*c3437056SNickeau try { 254*c3437056SNickeau /** 255*c3437056SNickeau * If the page does not need to be indexed, there is no run 256*c3437056SNickeau * and false is returned 257*c3437056SNickeau */ 258*c3437056SNickeau $indexedOrNot = idx_addPage($id, true, true); 259*c3437056SNickeau if ($indexedOrNot) { 260*c3437056SNickeau LogUtility::msg("The page {$id} ($pageCounter / $totalNumberOfPages) was indexed and replicated", LogUtility::LVL_MSG_INFO); 261*c3437056SNickeau } else { 262*c3437056SNickeau LogUtility::msg("The page {$id} ($pageCounter / $totalNumberOfPages) has an error", LogUtility::LVL_MSG_ERROR); 263*c3437056SNickeau } 264*c3437056SNickeau } catch (ExceptionComboRuntime $e) { 265*c3437056SNickeau LogUtility::msg("The page {$id} ($pageCounter / $totalNumberOfPages) has an error: " . $e->getMessage(), LogUtility::LVL_MSG_ERROR); 266*c3437056SNickeau } 267*c3437056SNickeau } 268*c3437056SNickeau /** 269*c3437056SNickeau * Process all backlinks 270*c3437056SNickeau */ 271*c3437056SNickeau echo "Processing Replication Request\n"; 272*c3437056SNickeau Event::dispatchEvent(PHP_INT_MAX); 273*c3437056SNickeau 274*c3437056SNickeau } 275*c3437056SNickeau 276*c3437056SNickeau private function analytics($namespaces = array(), $output = null, $depth = 0) 277007225e5Sgerardnico { 278007225e5Sgerardnico 279007225e5Sgerardnico $fileHandle = null; 280007225e5Sgerardnico if (!empty($output)) { 281007225e5Sgerardnico $fileHandle = @fopen($output, 'w'); 282007225e5Sgerardnico if (!$fileHandle) $this->fatal("Failed to open $output"); 283007225e5Sgerardnico } 284007225e5Sgerardnico 28537748cd8SNickeau /** 28637748cd8SNickeau * Run as admin to overcome the fact that 28737748cd8SNickeau * anonymous user cannot see all links and backlinks 28837748cd8SNickeau */ 28937748cd8SNickeau global $USERINFO; 29037748cd8SNickeau $USERINFO['grps'] = array('admin'); 29137748cd8SNickeau global $INPUT; 29237748cd8SNickeau $INPUT->server->set('REMOTE_USER', "cli"); 29337748cd8SNickeau 29437748cd8SNickeau $pages = FsWikiUtility::getPages($namespaces, $depth); 295007225e5Sgerardnico 296007225e5Sgerardnico 297007225e5Sgerardnico if (!empty($fileHandle)) { 298007225e5Sgerardnico $header = array( 299007225e5Sgerardnico 'id', 300007225e5Sgerardnico 'backlinks', 301007225e5Sgerardnico 'broken_links', 302007225e5Sgerardnico 'changes', 303007225e5Sgerardnico 'chars', 304007225e5Sgerardnico 'external_links', 305007225e5Sgerardnico 'external_medias', 306007225e5Sgerardnico 'h1', 307007225e5Sgerardnico 'h2', 308007225e5Sgerardnico 'h3', 309007225e5Sgerardnico 'h4', 310007225e5Sgerardnico 'h5', 311007225e5Sgerardnico 'internal_links', 312007225e5Sgerardnico 'internal_medias', 313007225e5Sgerardnico 'words', 314007225e5Sgerardnico 'score' 315007225e5Sgerardnico ); 316007225e5Sgerardnico fwrite($fileHandle, implode(",", $header) . PHP_EOL); 317007225e5Sgerardnico } 3189da76789Sgerardnico $pageCounter = 0; 319e8b2ff59SNickeau $totalNumberOfPages = sizeof($pages); 320*c3437056SNickeau while ($pageArray = array_shift($pages)) { 321*c3437056SNickeau $id = $pageArray['id']; 322*c3437056SNickeau $page = Page::createPageFromId($id); 323*c3437056SNickeau 324007225e5Sgerardnico 3259da76789Sgerardnico $pageCounter++; 326*c3437056SNickeau echo "Analytics Processing for the page {$id} ($pageCounter / $totalNumberOfPages)\n"; 327007225e5Sgerardnico 328*c3437056SNickeau /** 329*c3437056SNickeau * Analytics 330*c3437056SNickeau */ 331*c3437056SNickeau $analytics = $page->getAnalyticsDocument(); 332*c3437056SNickeau $data = $analytics->getOrProcessContent()->toArray(); 333*c3437056SNickeau 334007225e5Sgerardnico if (!empty($fileHandle)) { 335*c3437056SNickeau $statistics = $data[AnalyticsDocument::STATISTICS]; 336007225e5Sgerardnico $row = array( 337007225e5Sgerardnico 'id' => $id, 338*c3437056SNickeau 'backlinks' => $statistics[BacklinkCount::getPersistentName()], 339*c3437056SNickeau 'broken_links' => $statistics[AnalyticsDocument::INTERNAL_LINK_BROKEN_COUNT], 340*c3437056SNickeau 'changes' => $statistics[AnalyticsDocument::EDITS_COUNT], 341*c3437056SNickeau 'chars' => $statistics[AnalyticsDocument::CHAR_COUNT], 342*c3437056SNickeau 'external_links' => $statistics[AnalyticsDocument::EXTERNAL_LINK_COUNT], 343*c3437056SNickeau 'external_medias' => $statistics[AnalyticsDocument::EXTERNAL_MEDIA_COUNT], 344*c3437056SNickeau PageH1::PROPERTY_NAME => $statistics[AnalyticsDocument::HEADING_COUNT][PageH1::PROPERTY_NAME], 345*c3437056SNickeau 'h2' => $statistics[AnalyticsDocument::HEADING_COUNT]['h2'], 346*c3437056SNickeau 'h3' => $statistics[AnalyticsDocument::HEADING_COUNT]['h3'], 347*c3437056SNickeau 'h4' => $statistics[AnalyticsDocument::HEADING_COUNT]['h4'], 348*c3437056SNickeau 'h5' => $statistics[AnalyticsDocument::HEADING_COUNT]['h5'], 349*c3437056SNickeau 'internal_links' => $statistics[AnalyticsDocument::INTERNAL_LINK_COUNT], 350*c3437056SNickeau 'internal_medias' => $statistics[AnalyticsDocument::INTERNAL_MEDIA_COUNT], 351*c3437056SNickeau 'words' => $statistics[AnalyticsDocument::WORD_COUNT], 352*c3437056SNickeau 'low' => $data[AnalyticsDocument::QUALITY]['low'] 353007225e5Sgerardnico ); 354007225e5Sgerardnico fwrite($fileHandle, implode(",", $row) . PHP_EOL); 355007225e5Sgerardnico } 356*c3437056SNickeau 357007225e5Sgerardnico } 358007225e5Sgerardnico if (!empty($fileHandle)) { 359007225e5Sgerardnico fclose($fileHandle); 360007225e5Sgerardnico } 361007225e5Sgerardnico 362007225e5Sgerardnico } 36371f916b9Sgerardnico 364325fe0c5Sgerardnico 365*c3437056SNickeau private function deleteNonExistingPageFromDatabase() 36671f916b9Sgerardnico { 367*c3437056SNickeau LogUtility::msg("Starting: Deleting non-existing page from database"); 368*c3437056SNickeau $sqlite = Sqlite::createOrGetSqlite(); 369*c3437056SNickeau $request = $sqlite 370*c3437056SNickeau ->createRequest() 371*c3437056SNickeau ->setQuery("select id as \"id\" from pages"); 372*c3437056SNickeau $rows = []; 373*c3437056SNickeau try { 374*c3437056SNickeau $rows = $request 375*c3437056SNickeau ->execute() 376*c3437056SNickeau ->getRows(); 377*c3437056SNickeau } catch (ExceptionCombo $e) { 378*c3437056SNickeau LogUtility::msg("Error while getting the id pages. {$e->getMessage()}"); 379*c3437056SNickeau return; 380*c3437056SNickeau } finally { 381*c3437056SNickeau $request->close(); 38271f916b9Sgerardnico } 383*c3437056SNickeau $counter = 0; 384*c3437056SNickeau foreach ($rows as $row) { 385*c3437056SNickeau $counter++; 386*c3437056SNickeau $id = $row['id']; 38771f916b9Sgerardnico if (!page_exists($id)) { 38871f916b9Sgerardnico echo 'Page does not exist on the file system. Deleted from the database (' . $id . ")\n"; 389*c3437056SNickeau Page::createPageFromId($id)->getDatabasePage()->delete(); 390*c3437056SNickeau } 391*c3437056SNickeau } 392*c3437056SNickeau LogUtility::msg("Sync finished ($counter pages checked)"); 393*c3437056SNickeau 394*c3437056SNickeau 395*c3437056SNickeau } 396*c3437056SNickeau 397*c3437056SNickeau private function frontmatter($namespaces, $depth) 398*c3437056SNickeau { 399*c3437056SNickeau $pages = FsWikiUtility::getPages($namespaces, $depth); 400*c3437056SNickeau $pageCounter = 0; 401*c3437056SNickeau $totalNumberOfPages = sizeof($pages); 402*c3437056SNickeau $pagesWithChanges = []; 403*c3437056SNickeau $pagesWithError = []; 404*c3437056SNickeau $pagesWithOthers = []; 405*c3437056SNickeau $notChangedCounter = 0; 406*c3437056SNickeau while ($pageArray = array_shift($pages)) { 407*c3437056SNickeau $id = $pageArray['id']; 408*c3437056SNickeau $page = Page::createPageFromId($id); 409*c3437056SNickeau $pageCounter++; 410*c3437056SNickeau LogUtility::msg("Processing page {$id} ($pageCounter / $totalNumberOfPages) ", LogUtility::LVL_MSG_INFO); 411*c3437056SNickeau try { 412*c3437056SNickeau $message = MetadataFrontmatterStore::createFromPage($page) 413*c3437056SNickeau ->sync(); 414*c3437056SNickeau switch ($message->getStatus()) { 415*c3437056SNickeau case syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_NOT_CHANGED: 416*c3437056SNickeau $notChangedCounter++; 417*c3437056SNickeau break; 418*c3437056SNickeau case syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_DONE: 419*c3437056SNickeau $pagesWithChanges[] = $id; 420*c3437056SNickeau break; 421*c3437056SNickeau case syntax_plugin_combo_frontmatter::UPDATE_EXIT_CODE_ERROR: 422*c3437056SNickeau $pagesWithError[$id] = $message->getPlainTextContent(); 423*c3437056SNickeau break; 424*c3437056SNickeau default: 425*c3437056SNickeau $pagesWithOthers[$id] = $message->getPlainTextContent(); 426*c3437056SNickeau break; 427*c3437056SNickeau 428*c3437056SNickeau } 429*c3437056SNickeau } catch (ExceptionCombo $e) { 430*c3437056SNickeau $pagesWithError[$id] = $e->getMessage(); 431*c3437056SNickeau } 432*c3437056SNickeau 433*c3437056SNickeau } 434*c3437056SNickeau 435*c3437056SNickeau echo "\n"; 436*c3437056SNickeau echo "Result:\n"; 437*c3437056SNickeau echo "$notChangedCounter pages without any frontmatter modifications\n"; 438*c3437056SNickeau 439*c3437056SNickeau if (sizeof($pagesWithError) > 0) { 440*c3437056SNickeau echo "\n"; 441*c3437056SNickeau echo "The following pages had errors\n"; 442*c3437056SNickeau $pageCounter = 0; 443*c3437056SNickeau $totalNumberOfPages = sizeof($pagesWithError); 444*c3437056SNickeau foreach ($pagesWithError as $id => $message) { 445*c3437056SNickeau $pageCounter++; 446*c3437056SNickeau LogUtility::msg("Page {$id} ($pageCounter / $totalNumberOfPages): " . $message, LogUtility::LVL_MSG_ERROR); 447*c3437056SNickeau } 448*c3437056SNickeau } else { 449*c3437056SNickeau echo "No error\n"; 450*c3437056SNickeau } 451*c3437056SNickeau 452*c3437056SNickeau if (sizeof($pagesWithChanges) > 0) { 453*c3437056SNickeau echo "\n"; 454*c3437056SNickeau echo "The following pages had changed:\n"; 455*c3437056SNickeau $pageCounter = 0; 456*c3437056SNickeau $totalNumberOfPages = sizeof($pagesWithChanges); 457*c3437056SNickeau foreach ($pagesWithChanges as $id) { 458*c3437056SNickeau $pageCounter++; 459*c3437056SNickeau LogUtility::msg("Page {$id} ($pageCounter / $totalNumberOfPages) ", LogUtility::LVL_MSG_ERROR); 460*c3437056SNickeau } 461*c3437056SNickeau } else { 462*c3437056SNickeau echo "No changes\n"; 463*c3437056SNickeau } 464*c3437056SNickeau 465*c3437056SNickeau if (sizeof($pagesWithOthers) > 0) { 466*c3437056SNickeau echo "\n"; 467*c3437056SNickeau echo "The following pages had an other status"; 468*c3437056SNickeau $pageCounter = 0; 469*c3437056SNickeau $totalNumberOfPages = sizeof($pagesWithOthers); 470*c3437056SNickeau foreach ($pagesWithOthers as $id => $message) { 471*c3437056SNickeau $pageCounter++; 472*c3437056SNickeau LogUtility::msg("Page {$id} ($pageCounter / $totalNumberOfPages) " . $message, LogUtility::LVL_MSG_ERROR); 473*c3437056SNickeau } 47471f916b9Sgerardnico } 47571f916b9Sgerardnico } 47671f916b9Sgerardnico 477*c3437056SNickeau private function getStartPath($args) 478*c3437056SNickeau { 479*c3437056SNickeau $sizeof = sizeof($args); 480*c3437056SNickeau switch ($sizeof) { 481*c3437056SNickeau case 0: 482*c3437056SNickeau fwrite(STDERR, "The start path is mandatory and was not given"); 483*c3437056SNickeau exit(1); 484*c3437056SNickeau case 1: 485*c3437056SNickeau $startPath = $args[0]; 486*c3437056SNickeau if (!in_array($startPath, [":", "/"])) { 487*c3437056SNickeau // cleanId would return blank for a root 488*c3437056SNickeau $startPath = cleanID($startPath); 489*c3437056SNickeau } 490*c3437056SNickeau break; 491*c3437056SNickeau default: 492*c3437056SNickeau fwrite(STDERR, "Too much arguments given $sizeof"); 493*c3437056SNickeau exit(1); 494*c3437056SNickeau } 495*c3437056SNickeau return $startPath; 49671f916b9Sgerardnico } 497007225e5Sgerardnico} 498