diff --git a/assets/ts_src/ajax_ui.ts b/assets/ts_src/ajax_ui.ts index 5c293e9b..0004eeea 100644 --- a/assets/ts_src/ajax_ui.ts +++ b/assets/ts_src/ajax_ui.ts @@ -68,8 +68,12 @@ class AjaxUI { * Starts the ajax ui und execute handlers registered in addStartAction(). * Should be called in a document.ready, after handlers are set. */ - public start() + public start(disabled : boolean = false) { + if(disabled) { + return; + } + console.info("AjaxUI started!"); this.BASE = $("body").data("base-url") + "/"; @@ -227,6 +231,19 @@ class AjaxUI { { let options : JQueryFormOptions = { success: this.onAjaxComplete, + beforeSerialize: function() : boolean { + + //Update the content of textarea fields using CKEDITOR before submitting. + + //@ts-ignore + for(let name in CKEDITOR.instances) + { + //@ts-ignore + CKEDITOR.instances[name].updateElement(); + } + + return true; + }, beforeSubmit: function (arr, $form, options) : boolean { //When data-with-progbar is specified, then show progressbar. if($form.data("with-progbar") != undefined) { diff --git a/src/Controller/AttachmentTypeController.php b/src/Controller/AttachmentTypeController.php new file mode 100644 index 00000000..13cc82f5 --- /dev/null +++ b/src/Controller/AttachmentTypeController.php @@ -0,0 +1,97 @@ +createForm(BaseEntityAdminForm::class, $entity); + + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + $em->persist($entity); + $em->flush(); + } + + return $this->render('AdminPages/AttachmentTypeAdmin.html.twig', [ + 'entity' => $entity, + 'form' => $form->createView() + ]); + } + + /** + * @Route("/new") + * + * @return \Symfony\Component\HttpFoundation\Response + */ + public function new(Request $request, EntityManagerInterface $em) + { + $new_entity = new AttachmentType(); + + $this->denyAccessUnlessGranted('create', $new_entity); + + $form = $this->createForm(BaseEntityAdminForm::class, $new_entity); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + $em->persist($new_entity); + $em->flush(); + //$this->addFlash('success', $translator->trans('part.created_flash')); + + return $this->redirectToRoute('attachment_type_edit', ['id' => $new_entity->getID()]); + } + + return $this->render('AdminPages/AttachmentTypeAdmin.html.twig', [ + 'entity' => $new_entity, + 'form' => $form->createView() + ]); + } +} \ No newline at end of file diff --git a/src/Entity/AttachmentType.php b/src/Entity/AttachmentType.php index 5c99c437..7d56ee4a 100644 --- a/src/Entity/AttachmentType.php +++ b/src/Entity/AttachmentType.php @@ -23,6 +23,7 @@ declare(strict_types=1); namespace App\Entity; +use App\Validator\Constraints\NoneOfItsChildren; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; diff --git a/src/Entity/DBElement.php b/src/Entity/DBElement.php index 0211b27b..32cd3cfa 100644 --- a/src/Entity/DBElement.php +++ b/src/Entity/DBElement.php @@ -50,9 +50,11 @@ abstract class DBElement * Get the ID. The ID can be zero, or even negative (for virtual elements). If an elemenent is virtual, can be * checked with isVirtualElement(). * - * @return int the ID of this element + * Returns null, if the element is not saved to the DB yet. + * + * @return int|null the ID of this element */ - final public function getID(): int + final public function getID(): ?int { return (int) $this->id; } diff --git a/src/Entity/NamedDBElement.php b/src/Entity/NamedDBElement.php index 7ed29de7..da6dd995 100644 --- a/src/Entity/NamedDBElement.php +++ b/src/Entity/NamedDBElement.php @@ -74,20 +74,22 @@ abstract class NamedDBElement extends DBElement /** * Returns the last time when the element was modified. + * Returns null if the element was not yet saved to DB yet. * - * @return \DateTime The time of the last edit. + * @return \DateTime|null The time of the last edit. */ - public function getLastModified(): \DateTime + public function getLastModified(): ?\DateTime { return $this->lastModified; } /** * Returns the date/time when the element was created. + * Returns null if the element was not yet saved to DB yet. * - * @return \DateTime The creation time of the part. + * @return \DateTime|null The creation time of the part. */ - public function getAddedDate(): \DateTime + public function getAddedDate(): ?\DateTime { return $this->addedDate; } diff --git a/src/Entity/StructuralDBElement.php b/src/Entity/StructuralDBElement.php index c76e090a..d1fa2063 100644 --- a/src/Entity/StructuralDBElement.php +++ b/src/Entity/StructuralDBElement.php @@ -23,9 +23,9 @@ declare(strict_types=1); namespace App\Entity; -use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\Mapping as ORM; use Doctrine\ORM\PersistentCollection; +use App\Validator\Constraints\NoneOfItsChildren; /** * All elements with the fields "id", "name" and "parent_id" (at least). @@ -53,6 +53,7 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement protected $children; /** * @var StructuralDBElement + * @NoneOfItsChildren() */ protected $parent; @@ -85,7 +86,7 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement * Check if this element is a child of another element (recursive). * * @param StructuralDBElement $another_element the object to compare - * IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)! + * IMPORTANT: both objects to compare must be from the same class (for example two "Device" objects)! * * @return bool True, if this element is child of $another_element. * @@ -97,10 +98,10 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement //Check if both elements compared, are from the same type: if ($class_name != \get_class($another_element)) { - throw new \InvalidArgumentException('isChildOf() funktioniert nur mit Elementen des gleichen Typs!'); + throw new \InvalidArgumentException('isChildOf() only works for objects of the same type!'); } - if (null == $this->getID()) { // this is the root node + if (null == $this->getParent()) { // this is the root node return false; } @@ -116,13 +117,13 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement ******************************************************************************/ /** - * @brief Get the parent-ID + * Get the parent-ID * - * @retval integer * the ID of the parent element + * @return integer * the ID of the parent element * * NULL means, the parent is the root node * * the parent ID of the root node is -1 */ - public function getParentID(): int + protected function getParentID(): int { return $this->parent_id ?? self::ID_ROOT_ELEMENT; //Null means root element } @@ -139,14 +140,12 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement /** * Get the comment of the element. - * - * @param bool $parse_bbcode Should BBCode converted to HTML, before returning - * + * @return string the comment */ - public function getComment(bool $parse_bbcode = true): string + public function getComment(): ?string { - return htmlspecialchars($this->comment ?? ''); + return $this->comment; } /** @@ -179,8 +178,6 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement * @param string $delimeter the delimeter of the returned string * * @return string the full path (incl. the name of this element), delimeted by $delimeter - * - * @throws Exception if there was an error */ public function getFullPath(string $delimeter = self::PATH_DELIMITER_ARROW): string { @@ -189,9 +186,13 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement $this->full_path_strings[] = $this->getName(); $element = $this; - while (null != $element->parent) { + $overflow = 20; //We only allow 20 levels depth + + while (null != $element->parent && $overflow >= 0) { $element = $element->parent; $this->full_path_strings[] = $element->getName(); + //Decrement to prevent mem overflow. + $overflow--; } $this->full_path_strings = array_reverse($this->full_path_strings); @@ -219,143 +220,31 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement ******************************************************************************/ /** - * Change the parent ID of this element. - * - * @param int|null $new_parent_id * the ID of the new parent element - * * NULL if the parent should be the root node + * Sets the new parent object + * @param self $new_parent The new parent object + * @return StructuralDBElement */ - public function setParentID($new_parent_id): self + public function setParent(?self $new_parent) : self { - $this->parent_id = $new_parent_id; + /* + if ($new_parent->isChildOf($this)) { + throw new \InvalidArgumentException('You can not use one of the element childs as parent!'); + } */ + + $this->parent = $new_parent; return $this; } /** * Set the comment. - * * @param string $new_comment the new comment - * - * @throws Exception if there was an error + * @return StructuralDBElement */ - public function setComment(string $new_comment): self + public function setComment(?string $new_comment): self { $this->comment = $new_comment; return $this; } - - /******************************************************************************** - * - * Tree / Table Builders - * - *********************************************************************************/ - - /** - * Build a HTML tree with all subcategories of this element. - * - * This method prints a