X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/37bf7f11e4361902ad92ceaf6bd15f1f85b76188..refs/pull/1462/head:/app/Entities/Repos/EntityRepo.php
diff --git a/app/Entities/Repos/EntityRepo.php b/app/Entities/Repos/EntityRepo.php
index 6fc2689a5..a0934530f 100644
--- a/app/Entities/Repos/EntityRepo.php
+++ b/app/Entities/Repos/EntityRepo.php
@@ -1,5 +1,6 @@
books()->sync($syncData);
}
+ /**
+ * Append a Book to a BookShelf.
+ * @param Bookshelf $shelf
+ * @param Book $book
+ */
+ public function appendBookToShelf(Bookshelf $shelf, Book $book)
+ {
+ if ($shelf->contains($book)) {
+ return;
+ }
+
+ $maxOrder = $shelf->books()->max('order');
+ $shelf->books()->attach($book->id, ['order' => $maxOrder + 1]);
+ }
+
/**
* Change the book that an entity belongs to.
* @param string $type
* @param integer $newBookId
* @param Entity $entity
* @param bool $rebuildPermissions
- * @return \BookStack\Entities\Entity
+ * @return Entity
*/
public function changeBook($type, $newBookId, Entity $entity, $rebuildPermissions = false)
{
@@ -700,6 +720,7 @@ class EntityRepo
}
$doc = new DOMDocument();
+ libxml_use_internal_errors(true);
$doc->loadHTML(mb_convert_encoding('
'.$matchedPage->html.'', 'HTML-ENTITIES', 'UTF-8'));
$matchingElem = $doc->getElementById($splitInclude[1]);
if ($matchingElem === null) {
@@ -715,6 +736,7 @@ class EntityRepo
$innerContent .= $doc->saveHTML($childNode);
}
}
+ libxml_clear_errors();
$html = str_replace($matches[0][$index], trim($innerContent), $html);
}
@@ -728,13 +750,35 @@ class EntityRepo
*/
protected function escapeScripts(string $html) : string
{
- $scriptSearchRegex = '/.*?<\/script>/ms';
- $matches = [];
- preg_match_all($scriptSearchRegex, $html, $matches);
+ if ($html == '') {
+ return $html;
+ }
+
+ libxml_use_internal_errors(true);
+ $doc = new DOMDocument();
+ $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'));
+ $xPath = new DOMXPath($doc);
+
+ // Remove standard script tags
+ $scriptElems = $xPath->query('//body//*//script');
+ foreach ($scriptElems as $scriptElem) {
+ $scriptElem->parentNode->removeChild($scriptElem);
+ }
- foreach ($matches[0] as $match) {
- $html = str_replace($match, htmlentities($match), $html);
+ // Remove 'on*' attributes
+ $onAttributes = $xPath->query('//body//*/@*[starts-with(name(), \'on\')]');
+ foreach ($onAttributes as $attr) {
+ /** @var \DOMAttr $attr*/
+ $attrName = $attr->nodeName;
+ $attr->parentNode->removeAttribute($attrName);
}
+
+ $html = '';
+ $topElems = $doc->documentElement->childNodes->item(0)->childNodes;
+ foreach ($topElems as $child) {
+ $html .= $doc->saveHTML($child);
+ }
+
return $html;
}
@@ -745,7 +789,7 @@ class EntityRepo
*/
public function searchForImage($imageString)
{
- $pages = $this->entityQuery('page')->where('html', 'like', '%' . $imageString . '%')->get();
+ $pages = $this->entityQuery('page')->where('html', 'like', '%' . $imageString . '%')->get(['id', 'name', 'slug', 'book_id']);
foreach ($pages as $page) {
$page->url = $page->getUrl();
$page->html = '';
@@ -756,8 +800,8 @@ class EntityRepo
/**
* Destroy a bookshelf instance
- * @param \BookStack\Entities\Bookshelf $shelf
- * @throws \Throwable
+ * @param Bookshelf $shelf
+ * @throws Throwable
*/
public function destroyBookshelf(Bookshelf $shelf)
{
@@ -767,9 +811,9 @@ class EntityRepo
/**
* Destroy the provided book and all its child entities.
- * @param \BookStack\Entities\Book $book
+ * @param Book $book
* @throws NotifyException
- * @throws \Throwable
+ * @throws Throwable
*/
public function destroyBook(Book $book)
{
@@ -785,8 +829,8 @@ class EntityRepo
/**
* Destroy a chapter and its relations.
- * @param \BookStack\Entities\Chapter $chapter
- * @throws \Throwable
+ * @param Chapter $chapter
+ * @throws Throwable
*/
public function destroyChapter(Chapter $chapter)
{
@@ -804,7 +848,7 @@ class EntityRepo
* Destroy a given page along with its dependencies.
* @param Page $page
* @throws NotifyException
- * @throws \Throwable
+ * @throws Throwable
*/
public function destroyPage(Page $page)
{
@@ -827,12 +871,12 @@ class EntityRepo
/**
* Destroy or handle the common relations connected to an entity.
- * @param \BookStack\Entities\Entity $entity
- * @throws \Throwable
+ * @param Entity $entity
+ * @throws Throwable
*/
protected function destroyEntityCommonRelations(Entity $entity)
{
- \Activity::removeEntity($entity);
+ Activity::removeEntity($entity);
$entity->views()->delete();
$entity->permissions()->delete();
$entity->tags()->delete();
@@ -844,9 +888,9 @@ class EntityRepo
/**
* Copy the permissions of a bookshelf to all child books.
* Returns the number of books that had permissions updated.
- * @param \BookStack\Entities\Bookshelf $bookshelf
+ * @param Bookshelf $bookshelf
* @return int
- * @throws \Throwable
+ * @throws Throwable
*/
public function copyBookshelfPermissions(Bookshelf $bookshelf)
{