瀏覽代碼

checkin of everything

praktikant 3 周之前
父節點
當前提交
077020e3ce

+ 2 - 1
composer.json

@@ -12,7 +12,8 @@
         "n2n/n2n-impl-persistence-meta": "^7.3",
         "n2n/n2n-impl-persistence-orm": "^7.3",
         "n2n/n2n-impl-web-dispatch": "^7.3",
-        "n2n/n2n-impl-web-ui": "^7.3"
+        "n2n/n2n-impl-web-ui": "^7.3",
+        "n2n/n2n-bind": "^7.4"
     },
     "require-dev": {
         "n2n/hangar": "^7.2.0",

+ 107 - 1
composer.lock

@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "9d60596d53fbce2540799474e56ba846",
+    "content-hash": "985252d6b07c955f7f4b5edac3663be4",
     "packages": [
         {
             "name": "n2n/n2n",
@@ -122,6 +122,60 @@
             },
             "time": "2024-12-04T10:36:13+00:00"
         },
+        {
+            "name": "n2n/n2n-bind",
+            "version": "v7.4.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/n2n/n2n-bind.git",
+                "reference": "0f45991335bb15037ee42db4785737016d1945d2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/n2n/n2n-bind/zipball/0f45991335bb15037ee42db4785737016d1945d2",
+                "reference": "0f45991335bb15037ee42db4785737016d1945d2",
+                "shasum": ""
+            },
+            "require": {
+                "ext-ctype": "*",
+                "ext-mbstring": "*",
+                "n2n/n2n-reflection": "~7.4.1",
+                "n2n/n2n-spec-valobj": "~1.0",
+                "n2n/n2n-util": "~7.4.5",
+                "n2n/n2n-validation": "~7.4.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.6"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "n2n\\bind\\": "src/app/n2n/bind"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-3.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "Andreas von Burg",
+                    "email": "a@von-burg.net",
+                    "homepage": "https://www.von-burg.net/"
+                }
+            ],
+            "description": "bind/json support for n2n framework",
+            "homepage": "https://n2n.rocks/",
+            "keywords": [
+                "batch job",
+                "n2n"
+            ],
+            "support": {
+                "issues": "https://github.com/n2n/n2n-bind/issues",
+                "source": "https://github.com/n2n/n2n-bind/tree/v7.4.5"
+            },
+            "time": "2025-10-30T13:14:26+00:00"
+        },
         {
             "name": "n2n/n2n-cache",
             "version": "v7.4.0",
@@ -1076,6 +1130,58 @@
             },
             "time": "2025-11-04T16:16:27+00:00"
         },
+        {
+            "name": "n2n/n2n-validation",
+            "version": "v7.4.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/n2n/n2n-validation.git",
+                "reference": "40b87b7e32dce3366fbf1a903cbbdbbde5d5c408"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/n2n/n2n-validation/zipball/40b87b7e32dce3366fbf1a903cbbdbbde5d5c408",
+                "reference": "40b87b7e32dce3366fbf1a903cbbdbbde5d5c408",
+                "shasum": ""
+            },
+            "require": {
+                "ext-mbstring": "*",
+                "n2n/n2n-l10n": "~7.4",
+                "n2n/n2n-reflection": "~7.4",
+                "n2n/n2n-util": "~7.4.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "n2n\\validation\\": "src/app/n2n/validation"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "LGPL-3.0-or-later"
+            ],
+            "authors": [
+                {
+                    "name": "Andreas von Burg",
+                    "email": "a@von-burg.net",
+                    "homepage": "https://www.von-burg.net/"
+                }
+            ],
+            "description": "bind/json support for n2n framework",
+            "homepage": "http://n2n.rocks/",
+            "keywords": [
+                "batch job",
+                "n2n"
+            ],
+            "support": {
+                "issues": "https://github.com/n2n/n2n-validation/issues",
+                "source": "https://github.com/n2n/n2n-validation/tree/v7.4.4"
+            },
+            "time": "2025-11-03T11:02:40+00:00"
+        },
         {
             "name": "n2n/n2n-web",
             "version": "v7.4.5",

+ 27 - 5
src-php/app/internship/bo/Article.php

@@ -4,6 +4,8 @@ namespace internship\bo;
 use n2n\reflection\ObjectAdapter;
 use n2n\persistence\orm\attribute\ManyToOne;
 use n2n\persistence\orm\CascadeType;
+use n2n\web\http\controller\impl\HttpData;
+use n2n\web\http\StatusException;
 
 class Article extends ObjectAdapter implements \JsonSerializable {
 
@@ -12,9 +14,29 @@ class Article extends ObjectAdapter implements \JsonSerializable {
 	private string $text;
 	private string $title;
 
-	#[ManyToOne(cascade:CascadeType::PERSIST)]
+	#[ManyToOne(cascade: CascadeType::PERSIST)]
 	private ?ArticleGroup $articleGroup;
 
+	function __construct(?string $categoryName = null, ?string $text = null, ?string $title = null) {
+		if ($categoryName !== null) {
+			$this->categoryName = $categoryName;
+		}
+		if ($text !== null) {
+			$this->text = $text;
+		}
+		if ($title !== null) {
+			$this->title = $title;
+		}
+	}
+
+	/**
+	 * @throws StatusException
+	 */
+	static function fromHttpData(HttpData $httpData): Article {
+		return new Article($httpData->reqString('title'), $httpData->reqString('text'),
+				$httpData->reqEnum('categoryName', ['sport']))
+	}
+
 	/**
 	 * @return int
 	 */
@@ -72,7 +94,7 @@ class Article extends ObjectAdapter implements \JsonSerializable {
 	}
 
 	/**
-	 * @return string
+	 * @return ArticleGroup
 	 */
 	public function getArticleGroup(): ArticleGroup {
 		return $this->articleGroup;
@@ -80,9 +102,9 @@ class Article extends ObjectAdapter implements \JsonSerializable {
 
 
 	/**
-	 * @param string $articleGroup
+	 * @param ArticleGroup|null $articleGroup
 	 */
-	public function setArticleGroup(ArticleGroup $articleGroup): void {
+	public function setArticleGroup(ArticleGroup|null $articleGroup): void {
 		$this->articleGroup = $articleGroup;
 	}
 
@@ -92,7 +114,7 @@ class Article extends ObjectAdapter implements \JsonSerializable {
             'title' => $this->title,
             'categoryName' => $this->categoryName,
             'text' => $this->text,
-			'article_group_id' => $this->articleGroup?->getId(),
+			'articleGroupId' => $this->articleGroup?->getId(),
         ];
     }
 }

+ 10 - 4
src-php/app/internship/bo/ArticleGroup.php

@@ -11,7 +11,7 @@ class ArticleGroup extends ObjectAdapter implements \JsonSerializable{
 	private int $id;
 	private string $name;
 
-	#[OneToMany(Article::class, 'articleGroup', CascadeType::PERSIST)]
+	#[OneToMany(Article::class, 'articleGroup', CascadeType::ALL)]
 	private \ArrayObject $articles;
 
 	/**
@@ -43,16 +43,22 @@ class ArticleGroup extends ObjectAdapter implements \JsonSerializable{
 	}
 
 	/**
-	 * @return \ArrayObject
+	 * @return \ArrayObject<Article>
 	 */
 	public function getArticles(): \ArrayObject{
 		return $this->articles;
 	}
 
 	/**
-	 * @param \ArrayObject articles
+	 * @param \ArrayObject<Article> articles
 	 */
-	public function setArticles(\ArrayObject $articles): void{
+	public function setArticles(\ArrayObject $articles): void {
+		foreach ($this->articles as $article) {
+			$article->setArticleGroup(null);
+		}
+		foreach ($articles as $article) {
+			$article->setArticleGroup($this);
+		}
 		$this->articles = $articles;
 	}
 

+ 83 - 55
src-php/app/internship/controller/ArticleController.php

@@ -1,4 +1,5 @@
 <?php
+
 namespace internship\controller;
 
 use n2n\web\http\controller\ControllerAdapter;
@@ -8,6 +9,13 @@ use n2n\web\http\controller\ParamBody;
 use internship\bo\Article;
 use n2n\web\http\PageNotFoundException;
 use n2n\web\http\BadRequestException;
+use n2n\web\http\StatusException;
+use internship\model\ArticleGroupDao;
+use function PHPUnit\Framework\throwException;
+use n2n\web\http\controller\impl\HttpData;
+use n2n\bind\build\impl\Bind;
+use n2n\bind\mapper\impl\Mappers;
+use n2n\validation\validator\impl\Validators;
 
 /**
  * REST Controller
@@ -17,27 +25,30 @@ class ArticleController extends ControllerAdapter {
 	#[Inject]
 	private ArticleDao $articleDao;
 
+	#[Inject]
+	private ArticleGroupDao $articleGroupDao;
+
 	/**
 	 * Gibt den {@see Article} mit der entsprechenden id im JSON Format zurück.
 	 *
 	 * <ul>
-	 * 	<li>
-	 * 		Gib "irgendöpis" mit dem {@code echo} command aus.
-	 * 	</li>
-	 *	<li>
-	 * 		Ändere die Antwort nun zu einem gültigen json objekt {"hello" => "world"}. Übergebe dafür ein array der
-	 * 		Methode {@see $this->sendJson()}.
-	 * 	</li>
-	 * 	<li>
-	 * 		Implementiere und nutze die Methode {@see ArticleDao::getArticleById()}, um das entsprechende Artikel-Objekt
-	 * 		aus der Datenbank zu lesen und gebe diese anschliessend im JSON Format zurück.
+	 *    <li>
+	 *        Gib "irgendöpis" mit dem {@code echo} command aus.
+	 *    </li>
+	 *    <li>
+	 *        Ändere die Antwort nun zu einem gültigen json objekt {"hello" => "world"}. Übergebe dafür ein array der
+	 *        Methode {@see $this->sendJson()}.
+	 *    </li>
+	 *    <li>
+	 *        Implementiere und nutze die Methode {@see ArticleDao::getArticleById()}, um das entsprechende Artikel-Objekt
+	 *        aus der Datenbank zu lesen und gebe diese anschliessend im JSON Format zurück.
 	 *
-	 * 		Das Article-Objekt kannst du einfach {@see $this->sendJson()} übergeben, um einen validen JSON-Response zu
-	 * 		generieren.
-	 * 	</li>
-	 * 	<li>
-	 * 		Kann der Artikel nicht gefunden werden, werfe eine {@link PageNotFoundException}.
-	 * 	</li>
+	 *        Das Article-Objekt kannst du einfach {@see $this->sendJson()} übergeben, um einen validen JSON-Response zu
+	 *        generieren.
+	 *    </li>
+	 *    <li>
+	 *        Kann der Artikel nicht gefunden werden, werfe eine {@link PageNotFoundException}.
+	 *    </li>
 	 * </ul>
 	 *
 	 * @param int $articleId
@@ -59,23 +70,23 @@ class ArticleController extends ControllerAdapter {
 	 * Diese Methode kannst du im Browser testen. Pfad: localhost/[ordner name vom projekt]/src-php/public/api/articles
 	 *
 	 * <ul>
-	 * 	<li>
- 	 *		Implementiere und nutze die Methode {@see ArticleDao::getArticles()}, um Artikel aus der Datenbank zu lesen
-	 * 		und gebe diese anschliessend im JSON Format zurück.
+	 *    <li>
+	 *        Implementiere und nutze die Methode {@see ArticleDao::getArticles()}, um Artikel aus der Datenbank zu lesen
+	 *        und gebe diese anschliessend im JSON Format zurück.
 	 *
-	 * 		Article-Objekte kannst du einfach {@see $this->sendJson()} übergeben, um einen validen JSON-Response zu
-	 * 		generieren.
-	 * 	</li>
-	 * 	<li>
-	 * 		Wird ein $categoryName übergeben, gebe nur die Artikel aus, die über diesen Kategorienamen verfügen.
-	 * 	</li>
+	 *        Article-Objekte kannst du einfach {@see $this->sendJson()} übergeben, um einen validen JSON-Response zu
+	 *        generieren.
+	 *    </li>
+	 *    <li>
+	 *        Wird ein $categoryName übergeben, gebe nur die Artikel aus, die über diesen Kategorienamen verfügen.
+	 *    </li>
 	 * </ul>
 	 *
 	 * @param string|null $categoryName
 	 * @return void
 	 */
 	function getDoArticles(?string $categoryName = null): void {
-		if ($categoryName === null){
+		if ($categoryName === null) {
 			$this->sendJson($this->articleDao->getArticles());
 		} else {
 			$this->sendJson($this->articleDao->getArticlesByCategoryName($categoryName));
@@ -102,64 +113,63 @@ class ArticleController extends ControllerAdapter {
 	 *
 	 * @return void
 	 * @throws BadRequestException
+	 * @throws StatusException
 	 */
 	function postDoArticle(ParamBody $body): void {
-		$httpData = $body->parseJsonToHttpData();
-		$validCategoryNames = ["sport", "international", "national"];
-		if (!in_array($httpData->reqString("categoryName"), $validCategoryNames)) {
-			throw new BadRequestException();
-		}
 //		$article = new Article(["categoryName" => "sport", "title" => "All the Travel", "text" => "no 757576"]);
-//		$article = new Article($encodedArticle);
-		$article = new Article();
-		$article->setCategoryName($httpData->reqString("categoryName"));
-		$article->setTitle($httpData->reqString('title'));
-		$article->setText($httpData->reqString("text"));
+//		$article = new Article('sport', 'All the Travel', 'no 757576');
+		$httpData = $body->parseJsonToHttpData();
+
+		$article = Article::fromHttpData($httpData);
+		$article = new Article($httpData);
+		$newArticle = $this->updateArticle($body->parseJsonToHttpData(), new Article());
 		$this->beginTransaction();
-		$this->articleDao->saveArticle($article);
+		$this->articleDao->saveArticle($newArticle);
 		$this->commit();
+
+		$this->sendJson($newArticle);
 	}
 
 	/**
 	 * Editiere einen Artikel.
 	 *
 	 * <ul>
-	 * 	<li>
-	 * 		Der Kategoriename darf nur 'international','national' oder 'sport' sein.
-	 * 		Validiere dies und schmeisse im Fehlerfall eine: {@see BadRequestException}
-	 * 	</li>
-	 * 	<li>
-	 *		Finde den dazugehörigen {@see Article} und passe die Daten mit denjenigen Daten von gestern ab.
-	 * 	</li>
+	 *    <li>
+	 *        Der Kategoriename darf nur 'international','national' oder 'sport' sein.
+	 *        Validiere dies und schmeisse im Fehlerfall eine: {@see BadRequestException}
+	 *    </li>
+	 *    <li>
+	 *        Finde den dazugehörigen {@see Article} und passe die Daten mit denjenigen Daten von gestern ab.
+	 *    </li>
 	 *  <li>
-	 *		Implementiere eine neue Methode im {@see ArticleDao} und nenne die Methode {@see saveArticle(Article $article)}.
-	 * 	 </li>
+	 *        Implementiere eine neue Methode im {@see ArticleDao} und nenne die Methode {@see saveArticle(Article $article)}.
+	 *     </li>
 	 * </ul>
 	 *
 	 * @return void
 	 * @throws PageNotFoundException if article id not found
+	 * @throws BadRequestException if categoryName is invalid
+	 * @throws StatusException
 	 */
 	function putDoArticle(int $articleId, ParamBody $body): void {
-		$httpData = $body->parseJsonToHttpData();
-		$validCategoryNames = ["sport", "international", "national"];
-		if (!in_array($httpData->reqString("categoryName"), $validCategoryNames)){
-			throw new BadRequestException();
-		}
 		$existingArticle = $this->articleDao->getArticleById($articleId);
-		$existingArticle->setCategoryName($httpData->reqString("categoryName"));
-		$existingArticle->setTitle($httpData->reqString('title'));
-		$existingArticle->setText($httpData->reqString("text"));
+		if ($existingArticle === null) {
+			throw new PageNotFoundException();
+		}
+		$existingArticle = $this->updateArticle($body->parseJsonToHttpData(), $existingArticle);
 		$this->beginTransaction();
 		$this->articleDao->saveArticle($existingArticle);
 		$this->commit();
 
+		$this->sendJson($existingArticle);
+
 	}
 
 	/**
 	 * Löscht den {@see Article} mit der dazugehörigen Id.
 	 *
 	 * <ul>
-	 * 	<li>Mache eine neue Methode im {@see ArticleDao} und benenne sie "removeArticle(int articleId) </li>
+	 *    <li>Mache eine neue Methode im {@see ArticleDao} und benenne sie "removeArticle(int articleId) </li>
 	 * <ul>
 	 *
 	 * @return void
@@ -169,4 +179,22 @@ class ArticleController extends ControllerAdapter {
 		$this->articleDao->removeArticle($articleId);
 		$this->commit();
 	}
+
+	/**
+	 * @param $httpData
+	 * @return Article
+	 * @throws PageNotFoundException
+	 * @throws StatusException
+	 */
+	private function updateArticle(HttpData $httpData, Article $article): Article {
+		$article->setCategoryName($httpData->reqEnum('categoryName', ['sport', 'international', 'national']));
+		$article->setTitle($httpData->reqString('title'));
+		$article->setText($httpData->reqString('text'));
+		$existingArticleGroup = $this->articleGroupDao->getArticleGroupById($httpData->reqInt('articleGroupId'));
+		if ($existingArticleGroup === null){
+			throw new PageNotFoundException();
+		}
+		$article->setArticleGroup($existingArticleGroup);
+		return $article;
+	}
 }

+ 128 - 7
src-php/app/internship/controller/ArticleGroupController.php

@@ -1,4 +1,5 @@
 <?php
+
 namespace internship\controller;
 
 use n2n\web\http\controller\ControllerAdapter;
@@ -10,6 +11,9 @@ use n2n\web\http\controller\ParamBody;
 use internship\bo\Article;
 use n2n\web\http\PageNotFoundException;
 use n2n\web\http\BadRequestException;
+use n2n\web\http\controller\Param;
+use n2n\web\http\StatusException;
+use n2n\util\type\attrs\AttributePath;
 
 /**
  * REST Controller
@@ -22,16 +26,133 @@ class ArticleGroupController extends ControllerAdapter {
 	#[Inject]
 	private ArticleGroupDao $articleGroupDao;
 
-	function getDoArticlesGroups(): void {
-//		$this->sendJson($this->$articleDao->getArticleGroups($articleGroupId));
+	/**
+	 * Gibt den {@see ArticleGroup} mit der entsprechenden id im JSON Format zurück.
+	 *
+	 * @param int $articleGroupId
+	 * @return void
+	 * @throws PageNotFoundException if ArticleGroup could not be found.
+	 */
+	function getDoArticleGroup(int $articleGroupId): void {
+		$articleGroup = $this->articleGroupDao->getArticleGroupById($articleGroupId);
+		if ($articleGroup === null) {
+			throw new PageNotFoundException();
+		}
+		$this->sendJson($articleGroup);
 	}
 
-	function getDoArticle(int $articleGroupId): void {
-		$articleGroup = $this->articleGroupDao->getArticles($articleGroupId);
-		$this->sendJson($articleGroup);
+	/**
+	 * Send all Articles of the passed ArticleGroup id.
+	 *
+	 * @param int $articleGroupId
+	 * @return Article[]
+	 * @throws PageNotFoundException
+	 */
+	function getDoArticles(int $articleGroupId): void {
+		$articleGroup = $this->articleGroupDao->getArticleGroupById($articleGroupId);
+		if ($articleGroup === null) {
+			throw new PageNotFoundException();
+		}
+
+		$this->sendJson($articleGroup->getArticles()->getArrayCopy());
 	}
 
-	function getDoArticles(): void {
-		$this->sendJson($this->articleGroupDao->getArticles());
+	/**
+	 * Erhalte all ArtikelGroups.
+	 *
+	 * @return void
+	 */
+	function getDoArticleGroups(): void {
+		$this->sendJson($this->articleGroupDao->getArticleGroups());
+	}
+
+	/**
+	 * Speichere einen ArtikelGroup.
+	 *
+	 * @param ParamBody $body
+	 * @return void
+	 * @throws PageNotFoundException
+	 * @throws StatusException
+	 */
+	function postDoArticleGroup(ParamBody $body): void {
+		$httpData = $body->parseJsonToHttpData();
+		$newArticleGroup = new ArticleGroup();
+		$newArticleGroup->setName($httpData->reqString("name"));
+//		var_dump($httpData->has("articleIds"));
+//		var_dump($httpData->containsAttribute(AttributePath::create("articleIds")));
+		if ($httpData->has("articleIds")) {
+			$articles = $this->fetchArticles($httpData->reqArray('articleIds'));
+			$newArticleGroup->setArticles($articles);
+		}
+		$this->beginTransaction();
+		$this->articleGroupDao->saveArticleGroup($newArticleGroup);
+		$this->commit();
+	}
+
+	/**
+	 * Editiere einen ArtikelGroup.
+	 *
+	 * @param int $articleGroupId
+	 * @param ParamBody $body
+	 * @return void
+	 * @throws PageNotFoundException if articleGroup id not found
+	 * @throws StatusException
+	 */
+	function putDoArticleGroup(int $articleGroupId, ParamBody $body): void {
+		$existingArticleGroup = $this->articleGroupDao->getArticleGroupById($articleGroupId);
+		if ($existingArticleGroup === null) {
+			throw new PageNotFoundException();
+		}
+
+		$httpData = $body->parseJsonToHttpData();
+		$existingArticleGroup->setName($httpData->reqString("name"));
+		if ($httpData->has('articleIds')) {
+			$articleIds = $httpData->reqArray('articleIds');
+			$articleIds = $this->fetchArticles($articleIds);
+			$existingArticleGroup->setArticles($articleIds);
+		}
+		$this->beginTransaction();
+		$this->articleGroupDao->saveArticleGroup($existingArticleGroup);
+		$this->commit();
 	}
+
+	/**
+	 * Löscht den {@see ArticleGroup} mit der dazugehörigen Id.
+	 *
+	 * @param int $articleGroupId
+	 * @return void
+	 * @throws PageNotFoundException
+	 */
+	function deleteDoArticleGroup(int $articleGroupId): void {
+		$existingArticleGroup = $this->articleGroupDao->getArticleGroupById($articleGroupId);
+		if($existingArticleGroup === null){
+			throw new PageNotFoundException();
+		}
+		$this->beginTransaction();
+
+		$this->articleGroupDao->removeArticleGroup($articleGroupId);
+		$this->commit();
+	}
+
+
+	/**
+	 * Hole alle angegebenen {@see Articel} und setze bei diesen die angegebene {@see ArticleGroup}
+	 *
+	 * @param int[] $articleIds
+	 * @return \ArrayObject
+	 * @throws PageNotFoundException
+	 */
+	private function fetchArticles(array $articleIds): \ArrayObject {
+		$connectedArticles = [];
+		foreach ($articleIds as $articleId) {
+			$existingArticle = $this->articleDao->getArticleById($articleId);
+			if ($existingArticle === null) {
+				throw new PageNotFoundException();
+			}
+			$connectedArticles[] = $existingArticle;
+		}
+		return new \ArrayObject($connectedArticles);
+	}
+
+
 }

+ 1 - 1
src-php/app/internship/model/ArticleDao.php

@@ -74,7 +74,7 @@ class ArticleDao {
 	 * @param int $id
 	 * @return void
 	 */
-	function removeArticle(int $id){
+	function removeArticle(int $id): void{
 		$articleToBeRemoved = $this->em->find(Article::class, $id);
 		$this->em->remove($articleToBeRemoved);
 	}

+ 34 - 2
src-php/app/internship/model/ArticleGroupDao.php

@@ -16,11 +16,43 @@ class ArticleGroupDao {
 	}
 
 	/**
-	 * Gebe alle {@see Article}-Objekte, nach id absteigend sortiert, zurück.
+	 * Gebe alle {@see ArticleGroup}-Objekte, nach id absteigend sortiert, zurück.
 	 *
+	 * @return ArticleGroup[]
+	 */
+	function getArticleGroups(): array {
+		$criteria = $this->em->createNqlCriteria("SELECT ag FROM ArticleGroup ag");
+		return $criteria->toQuery()->fetchArray();
+	}
+
+	/**
+	 * Gebe den {@see ArticleGroup} mit der enstprechenden ID zurück.
+	 *
+	 * @param int $id
 	 * @return ArticleGroup
 	 */
-	function getArticles(int $id): ArticleGroup {
+	function getArticleGroupById(int $id): ?ArticleGroup {
 		return $this->em->find(ArticleGroup::getClass(), $id);
 	}
+
+	/**
+	 * Speichere den {@see ArticleGroup}.
+	 *
+	 * @param ArticleGroup $articleGroup
+	 * @return null
+	 */
+	function saveArticleGroup(ArticleGroup $articleGroup) {
+		$this->em->persist($articleGroup);
+	}
+
+	/**
+	 * Entferne den {@see ArticleGroup} mit der entsprechenden Id.
+	 *
+	 * @param int $id
+	 * @return void
+	 */
+	function removeArticleGroup(int $id): void{
+		$articleGroupToRemove = $this->em->find(ArticleGroup::getClass(), $id);
+		$this->em->remove($articleGroupToRemove);
+	}
 }