Add base64 image support
This commit is contained in:
		
							parent
							
								
									140aed3586
								
							
						
					
					
						commit
						f8b5a0fd50
					
				| 
						 | 
					@ -1,9 +1,13 @@
 | 
				
			||||||
<?php namespace BookStack\Entities\Tools;
 | 
					<?php namespace BookStack\Entities\Tools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use BookStack\Auth\Permissions\PermissionService;
 | 
				
			||||||
use BookStack\Entities\Models\Page;
 | 
					use BookStack\Entities\Models\Page;
 | 
				
			||||||
use BookStack\Entities\Tools\Markdown\CustomStrikeThroughExtension;
 | 
					use BookStack\Entities\Tools\Markdown\CustomStrikeThroughExtension;
 | 
				
			||||||
use BookStack\Facades\Theme;
 | 
					use BookStack\Facades\Theme;
 | 
				
			||||||
use BookStack\Theming\ThemeEvents;
 | 
					use BookStack\Theming\ThemeEvents;
 | 
				
			||||||
 | 
					use BookStack\Uploads\Image;
 | 
				
			||||||
 | 
					use BookStack\Uploads\ImageRepo;
 | 
				
			||||||
 | 
					use BookStack\Uploads\ImageService;
 | 
				
			||||||
use DOMDocument;
 | 
					use DOMDocument;
 | 
				
			||||||
use DOMNodeList;
 | 
					use DOMNodeList;
 | 
				
			||||||
use DOMXPath;
 | 
					use DOMXPath;
 | 
				
			||||||
| 
						 | 
					@ -30,6 +34,7 @@ class PageContent
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    public function setNewHTML(string $html)
 | 
					    public function setNewHTML(string $html)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $html = $this->saveBase64Images($this->page, $html);
 | 
				
			||||||
        $this->page->html = $this->formatHtml($html);
 | 
					        $this->page->html = $this->formatHtml($html);
 | 
				
			||||||
        $this->page->text = $this->toPlainText();
 | 
					        $this->page->text = $this->toPlainText();
 | 
				
			||||||
        $this->page->markdown = '';
 | 
					        $this->page->markdown = '';
 | 
				
			||||||
| 
						 | 
					@ -60,6 +65,60 @@ class PageContent
 | 
				
			||||||
        return $converter->convertToHtml($markdown);
 | 
					        return $converter->convertToHtml($markdown);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * Convert all base64 image data to saved images
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    public function saveBase64Images(Page $page, string $htmlText): string
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($htmlText == '') {
 | 
				
			||||||
 | 
					            return $htmlText;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        libxml_use_internal_errors(true);
 | 
				
			||||||
 | 
					        $doc = new DOMDocument();
 | 
				
			||||||
 | 
					        $doc->loadHTML(mb_convert_encoding($htmlText, 'HTML-ENTITIES', 'UTF-8'));
 | 
				
			||||||
 | 
					        $container = $doc->documentElement;
 | 
				
			||||||
 | 
					        $body = $container->childNodes->item(0);
 | 
				
			||||||
 | 
					        $childNodes = $body->childNodes;
 | 
				
			||||||
 | 
					        $xPath = new DOMXPath($doc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Get all img elements with image data blobs
 | 
				
			||||||
 | 
					        $imageNodes = $xPath->query('//img[contains(@src, \'data:image\')]');
 | 
				
			||||||
 | 
					        foreach($imageNodes as $imageNode) {
 | 
				
			||||||
 | 
					            $imageSrc = $imageNode->getAttribute('src');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # Parse base64 data
 | 
				
			||||||
 | 
					            $result = preg_match('"data:image/[a-zA-Z]*(;base64,[a-zA-Z0-9+/\\= ]*)"', $imageSrc, $matches);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if($result === 1) {
 | 
				
			||||||
 | 
					                $base64ImageData = $matches[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                $image = new Image();
 | 
				
			||||||
 | 
					                $imageService = app()->make(ImageService::class);
 | 
				
			||||||
 | 
					                $permissionService = app(PermissionService::class);
 | 
				
			||||||
 | 
					                $imageRepo = new ImageRepo(new Image(), $imageService, $permissionService, $page);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                # Use existing saveDrawing method used for Drawio diagrams
 | 
				
			||||||
 | 
					                $image = $imageRepo->saveDrawing($base64ImageData, $page->id);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                // Create a new img element with the saved image URI
 | 
				
			||||||
 | 
					                $newNode = $doc->createElement('img');
 | 
				
			||||||
 | 
					                $newNode->setAttribute('src', $image->path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // Replace the old img element
 | 
				
			||||||
 | 
					                $imageNode->parentNode->replaceChild($newNode, $imageNode);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Generate inner html as a string
 | 
				
			||||||
 | 
					        $html = '';
 | 
				
			||||||
 | 
					        foreach ($childNodes as $childNode) {
 | 
				
			||||||
 | 
					            $html .= $doc->saveHTML($childNode);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return $html;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Formats a page's html to be tagged correctly within the system.
 | 
					     * Formats a page's html to be tagged correctly within the system.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue