92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
		
		
			
		
	
	
			92 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								namespace BookStack\Console\Commands;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								use Illuminate\Console\Command;
							 | 
						||
| 
								 | 
							
								use Illuminate\Database\Connection;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class UpdateUrl extends Command
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The name and signature of the console command.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @var string
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected $signature = 'bookstack:update-url
							 | 
						||
| 
								 | 
							
								                            {oldUrl : URL to replace}
							 | 
						||
| 
								 | 
							
								                            {newUrl : URL to use as the replacement}';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The console command description.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @var string
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected $description = 'Find and replace the given URLs in your BookStack database';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    protected $db;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Create a new command instance.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return void
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function __construct(Connection $db)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->db = $db;
							 | 
						||
| 
								 | 
							
								        parent::__construct();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Execute the console command.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return mixed
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    public function handle()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $oldUrl = str_replace("'", '', $this->argument('oldUrl'));
							 | 
						||
| 
								 | 
							
								        $newUrl = str_replace("'", '', $this->argument('newUrl'));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $urlPattern = '/https?:\/\/(.+)/';
							 | 
						||
| 
								 | 
							
								        if (!preg_match($urlPattern, $oldUrl) || !preg_match($urlPattern, $newUrl)) {
							 | 
						||
| 
								 | 
							
								            $this->error("The given urls are expected to be full urls starting with http:// or https://");
							 | 
						||
| 
								 | 
							
								            return 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$this->checkUserOkayToProceed($oldUrl, $newUrl)) {
							 | 
						||
| 
								 | 
							
								            return 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $columnsToUpdateByTable = [
							 | 
						||
| 
								 | 
							
								            "attachments" => ["path"],
							 | 
						||
| 
								 | 
							
								            "pages" => ["html", "text", "markdown"],
							 | 
						||
| 
								 | 
							
								            "images" => ["url"],
							 | 
						||
| 
								 | 
							
								            "comments" => ["html", "text"],
							 | 
						||
| 
								 | 
							
								        ];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        foreach ($columnsToUpdateByTable as $table => $columns) {
							 | 
						||
| 
								 | 
							
								            foreach ($columns as $column) {
							 | 
						||
| 
								 | 
							
								                $changeCount = $this->db->table($table)->update([
							 | 
						||
| 
								 | 
							
								                    $column => $this->db->raw("REPLACE({$column}, '{$oldUrl}', '{$newUrl}')")
							 | 
						||
| 
								 | 
							
								                ]);
							 | 
						||
| 
								 | 
							
								                $this->info("Updated {$changeCount} rows in {$table}->{$column}");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $this->info("URL update procedure complete.");
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Warn the user of the dangers of this operation.
							 | 
						||
| 
								 | 
							
								     * Returns a boolean indicating if they've accepted the warnings.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    protected function checkUserOkayToProceed(string $oldUrl, string $newUrl): bool
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $dangerWarning = "This will search for \"{$oldUrl}\" in your database and replace it with  \"{$newUrl}\".\n";
							 | 
						||
| 
								 | 
							
								        $dangerWarning .= "Are you sure you want to proceed?";
							 | 
						||
| 
								 | 
							
								        $backupConfirmation = "This operation could cause issues if used incorrectly. Have you made a backup of your existing database?";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $this->confirm($dangerWarning) && $this->confirm($backupConfirmation);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |