Modul pmessage

Hier dreht sich alles um die auf der Webseite veröffentlichten Tutorials. // This forum is all about the APF tutorials.
Antworten
Avedo

Modul pmessage

Beitrag von Avedo » 18.03.2010, 19:36:19

Hallo zusammen!

Ich habe mich soeben mal mit einer einfachen Implementierung eines pmessage Moduls beschäftigt, dass ich euch nachfolgend vorstellen möchte. Nun mag sich einigen die Frage stellen, was das überhaupt ist. Eigentlich relativ einfach. Es handelt sich dabei um ein Modul, das es den registrierten Benutzern einer Applikation erlaubt, sich gegenseitig kleine Nachrichten zukommen zu lassen.

Dem Modul liegt die nachfolgende Ordnerstruktur zu Grunde, die unter apps/modules/ angelegt wurde.

Code: Alles auswählen

pmessage
|-+ biz
|-+ data
  |- scripts
|-+ pres
  |- documentcontroller
  |- templates
Als erstes legt man im templates-Ordner die Datei main.html an, in die man vorerst irgendetwas schreiben.

Danach kann man such um die Implementierung der Domänen Objekte Message und Postman kümmern. Das gestaltet sich in diesem Fall recht simpel.

Code: Alles auswählen

<?php

/**
 * Represents the Message domain object of the pmessage modul.
 *
 * @author Andreas Wilhelm
 * @version
 * Version 0.1, 18.03.2010<br />
 */
final class Message {

	/**
	 * @private
	 * Id of the message.
	 */
	private $_id;

	/**
	 * @private
	 * The author of this message.
	 */
	private $_author;

	/**
	 * @private
	 * The receiver of this message.
	 */
	private $_receiver;

	/**
	 * @private
	 * The subject of this message.
	 */
	private $_subject;

	/**
	 * @private
	 * The message body.
	 */
	private $_body;

	/**
	 * @private
	 * The timestamp of the creation of this message.
	 */
	private $_date;

	/**
	 * @public
	 *
	 * Returns the author of this message.
	 *
	 * @return User $author The author of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getAuthor() {
		return $this->_author;
	}

	/**
	 * @public
	 *
	 * Returns the receiver of this message.
	 *
	 * @return User $receiver The receiver of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getReceiver() {
		return $this->_receiver;
	}

	/**
	 * @public
	 *
	 * Returns the subject of this message.
	 *
	 * @return String $subject The subject of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getSubject() {
		return $this->_subject;
	}

	/**
	 * @public
	 *
	 * Returns the body of this message.
	 *
	 * @return String $body The body of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getBody() {
		return $this->_body;
	}
	
	/**
	 * @public
	 *
	 * Returns the timestamp of the creation of this message.
	 *
	 * @return String $date The timestamp.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getDate() {
		return $this->_date;
	}
	
	/**
	 * @public
	 *
	 * Returns the id of this message.
	 *
	 * @return int $id The message-id.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function getId() {
		return $this->_id;
	}

	/**
	 * @public
	 *
	 * Sets the author of this message.
	 *
	 * @param User $author The author of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setAuthor($author) {
		$this->_author = $author;
	}

	/**
	 * @public
	 *
	 * Sets the receiver of this message.
	 *
	 * @param User $receiver The receiver of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setReceiver($receiver) {
		$this->_receiver = $receiver;
	}

	/**
	 * @public
	 *
	 * Sets the subject of this message.
	 *
	 * @param String $subject The subject of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setSubject($subject) {
		$this->_subject = $subject;
	}

	/**
	 * @public
	 *
	 * Sets the body of this message.
	 *
	 * @param String $body The body of the message.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setBody($body) {
		$this->_body = $body;
	}
	
	/**
	 * @public
	 *
	 * Sets the timestamp of the creation of this message.
	 *
	 * @param String $date The timestamp.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setDate($date) {
		$this->_date = $date;
	}
	
	/**
	 * @public
	 *
	 * Sets the id of this message.
	 *
	 * @param int $id The message-id.
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010
	 */
	public function setId($id) {
		$this->_id = $id;
	}
}

?>

Code: Alles auswählen

<?php

/**
 * The postman domain object.
 *
 * @author Andreas Wilhelm
 * @version
 * Version 0.1, 18.03.2010<br />
 */
final class Postman {

	/**
	 * @private
	 * Messages received by the current user.
	 */
	private $_inbox = array();

	/**
	 * @private
	 * Messages sent by the current user
	 * and read by the receiver.
	 */
	private $_outgoing = array();

	/**
	 * @private
	 * Messages sent by the current user
	 * and and read by the receiver yet.
	 */
	private $_sent = array();

	/**
	 * @private
	 * The user domain object.
	 */
	private $_user;

	/**
	 * @public
	 *
	 * Returns all messages reveived by the current user.
	 *
	 * @return array $inbox The message list
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function getInboxMessages(){
		return $this->__Inbox;
	}

	/**
	 * @public
	 *
	 * Sets the list of messages reveived by the current user.
	 *
	 * @param Message[] $inbox A list of messages
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function setInboxMessages($inbox){
		$this->__Inbox = $inbox;
	}

	/**
	 * @public
	 *
	 * Adds an entry to the list.
	 *
	 * @param Message $message An message object
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function addMessageToInbox($message){
		$this->__Inbox[] = $message;
	}

	/**
	 * @public
	 *
	 * Returns all messages sent by the current user,
	 * but not read by the receiver yet.
	 *
	 * @return Message[] $outgoing The message list
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function getOutgoingMessages(){
		return $this->_outgoing;
	}

	/**
	 * @public
	 *
	 * Sets the list of messages sent by the current user,
	 * but not read by the receiver yet.
	 *
	 * @param Message[] $outgoing A list of messages
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function setOutgoingMessages($outgoing){
		$this->_outgoing = $outgoing;
	}

	/**
	 * @public
	 *
	 * Adds an entry to the list.
	 *
	 * @param Message $message An message object
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function addMessageToOutgoing($message){
		$this->_outgoing[] = $message;
	}

	/**
	 * @public
	 *
	 * Returns all messages sent by the current user.
	 *
	 * @return Message[] $sent The message list
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function getSentMessages(){
		return $this->_sent;
	}

	/**
	 * @public
	 *
	 * Sets the list of messages sent by the current user.
	 *
	 * @param Message[] $sent A list of messages
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function setSentMessages($sent){
		$this->_sent = $sent;
	}

	/**
	 * @public
	 *
	 * Adds an message to the list.
	 *
	 * @param Message $message An message object
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function addMessageToSent($message){
		$this->_sent[] = $message;
	}

	/**
	 * @public
	 *
	 * Returns the user domain object of the user
	 * that owns the current postbox.
	 *
	 * @return User $user The owning user
	 *
	 * @author Andreas Wilhelm
	 * @version
	 * Version 0.1, 18.03.2010<br />
	 */
	public function getOwner(){
		return $this->_user;
	}
}

?>
Ein Benutzer Objekt sollte man in diesem Fall nicht brauchen, da man einfach auf das Objekt aus dem UmgtManager zurückgreifen können.

Werde diesen Thread in den kommenden Stunden und Tagen noch ein bisschen weiterführen. Würde mich über Kommentare, Anmerkungen oder Hilfe freuen.

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 18.03.2010, 23:01:51

Hallo Andreas,

das hört sich gut an. Sofern du - was ich denke - ein komplettes Tutorial schreiben möchtest, bietet sich das Wiki an. Dort kann man einfacher Fließtext platzieren als hier im Forum. Schon mal jetzt danke für dein Engagement! :geek:

Hier ein paar erste Kommentare:
  • Soweit ich dein Vorhaben verstanden habe, sind in deiner Domäne die Objekte "User" und "Message" relevant. "Postman" klingt für mich ein bischen wie eie Business-Komponente, nicht wie ein Domänen-Objekt. Grund: der "Postman" steuert den Nachrichten-Versand.
  • Die Formulierung von addMessageToSent() klingt etwas "umständlich". Einfacher und intuitiver hört sich für mich sendMessage(Message $message) an.
  • Was die Integration mit dem UmgtManager angeht muss man etwas "vorsichtig" sein. Grund: dieser baut auf den GenericORMapper auf und nutzt daher das GenericDomainObject als generische Repräsentation eines Domänen-Objekts. Für deine Anwendung ist es daher vielleicht schöner, ein GenericDomainObject vom Typ "User" nochmal in eine eigene Klasse User zu wrappen. Muss nicht sein, sieht aber in der Signatur der Methoden schöner aus. Z.B. setOwner(User $user)
Viele Grüße,
Christian

Avedo

Re: Modul pmessage

Beitrag von Avedo » 19.03.2010, 13:14:41

Einen wunderschönen guten Morgen!

Danke für deine Anmerkungen. Dazu habe ich jedoch gleich ein paar Fragen.
Soweit ich dein Vorhaben verstanden habe, sind in deiner Domäne die Objekte "User" und "Message" relevant.
Das ist richtig.
der "Postman" steuert den Nachrichten-Versand.
Das ist nicht ganz richtig, da der Postman eigentlich eine Postbox ist. :D Er ist weniger für den Versand, sondern eher für die Bereitstellung der einzelnen Emails eines Benutzers verantwortlich. Sent war daher auch so gemeint, dass es sich um bereits versandte, jedoch noch ungelesene Emails handelt. Ich habe das ganze jedoch noch einmal überdacht und mir überlegt diesen Punkt wegfallen zu lassen.
Einfacher und intuitiver hört sich für mich sendMessage(Message $message) an.
Das würde doch eigentlich eher in den entsprechenden Controller gehören, oder bist du der Meinung, dass der Postman bereits der Controller sein sollte?
Für deine Anwendung ist es daher vielleicht schöner, ein GenericDomainObject vom Typ "User" nochmal in eine eigene Klasse User zu wrappen.
Eigentlich hast du schon recht, die Signatur der Methode wäre sicherlich eingängiger, jedoch arbeite ich ja bereits intern mit dem UmgtManager. Es sollen sich ja nur registrierte Benutzer gegenseitig Nachrichten schicken können. Macht das Wrappen denn dann noch einen Sinn. Das ganze sollte dann ja einfach so aussehen.

Code: Alles auswählen

class User extends GenericDomainObject {
   public function User() {
      parent::GenericDomainObject('User');
   }
} 
Oder sehe ich da etwas falsch?

Mir ist außerdem aufgefallen, dass es zwei guestbook-Pakete gibt, wobei im ersteren alle DomainObjekte vom Typ BaseObjekt erben. Mich würde interessieren, wieso das geändert wurde und wieso man an dieser Stelle nicht einfach gleich mit dem GenericDomainObnject arbeitet.

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 19.03.2010, 17:27:00

Hallo Andreas,
Das ist nicht ganz richtig, da der Postman eigentlich eine Postbox ist. :D Er ist weniger für den Versand, sondern eher für die Bereitstellung der einzelnen Emails eines Benutzers verantwortlich.
Dann sollte es auch Postbox heißen. ;) Sofern das so ist, brauchen wir aber noch eine Komponente, die Postboxes verwaltet - einen PostboxService.
Sent war daher auch so gemeint, dass es sich um bereits versandte, jedoch noch ungelesene Emails handelt. Ich habe das ganze jedoch noch einmal überdacht und mir überlegt diesen Punkt wegfallen zu lassen.
Im Kontext Postbox macht das ja auch wieder Sinn.
Das würde doch eigentlich eher in den entsprechenden Controller gehören, oder bist du der Meinung, dass der Postman bereits der Controller sein sollte?
Der Postman oder PostboxService sollte das IMHO handhaben und einem Document-Controller eine solche Methode zur Verfügung stellen.
Das ganze sollte dann ja einfach so aussehen.
Nicht ganz. Dir fehlen die konkreten Methoden. Daher würde ich nach dem Decorator Pattern folgendes forschlagen:

Code: Alles auswählen

class User {

   public function User(GenericDomainObject $user = null){
      if($user == null){
         $this->user = new GenericDomainObject('User');
      } else {
         $this->user = $user;
      }
   }
   public function getUsername(){
      return $this->user->getProperty('Username');
   }
   public function setUsername($username){
      $this->user->setProperty('Username',$username);
   }

   ...

   public function getExternalRepresentation(){
      return $this->user;
   }
}
Mir ist außerdem aufgefallen, dass es zwei guestbook-Pakete gibt, wobei im ersteren alle DomainObjekte vom Typ BaseObjekt erben. Mich würde interessieren, wieso das geändert wurde und wieso man an dieser Stelle nicht einfach gleich mit dem GenericDomainObnject arbeitet.
Die beiden Pakete zeigen genau die beiden möglichen Ansätze auf. Entweder ich implementiere das Mapping komplett jedes mal selbst oder ich verwende einen Mapper (guestbook2009). Weiterhin habe ich bei der zweiten Möglichkeit noch die Alternativen die generischen Domänen-Objekte des Mappers direkt in der Applikation zu verwenden (siehe Usermanagement) oder diese nochmal zu kapseln (guestbook2009). Alle Vorgehensweise sind richtig, verfolgen nur eine andere Zielsetzung.
Die erste (selbst Mapper implementieren) halte ich für zu aufwendig, denn das ist mechanische Arbeit, die man sich nicht jedesmal antun muss. Die generischen Domänen-Objekte zu verwenden ist sehr einfach und man spart sich Zeit, möchte man die Datenschicht nur austauschbar halten oder werden die Domänen-Objekte aus mehreren Quellen gespeist, sind eigene Domänen-Objekte immer besser.

Ich hoffe, das erklärt ein wenig die unterschiedlichen Vorgehensweisen. Das guestbook2009 ist sicher das komplexeste, da gibt es aber auf der Artikel-Seite auch zwei sehr ausführliche Artikel zum Aufbau und zu den Gründen, warum das so implementiert wurde.
Viele Grüße,
Christian

Avedo

Re: Modul pmessage

Beitrag von Avedo » 19.03.2010, 17:40:25

Hallo Christian!

Danke für deine Antwort. Obwohl es wohl keinem der gängigen Entwurfsmethoden entspricht, werde ich mich die nächste Zeit daran setzen ein geeignetes ServiceObjekt zu entwerfen und zu implementieren. Selbiges werde ich auch mit dem Mapper machen, wobei ich nach dem Beispiel guestbook2009 vorgehen werde.

Jedoch habe ich noch eine Frage. Die Besucher meiner Seite sollen sich ja auf meiner Seite mit Hilfe eines Login-Formulars anmelden können. Nach erfolgreicher Anmeldung soll das Login-Formular verschwinden und ein Menü an seine Stelle treten, das je nach Status kürzer oder länger sein kann. In angemeldetem Zustand sollen die Benutzer nun in der Lage sein, den anderen Benutzern der Applikation Nachrichten zu schicken (funktioniert wie die PNs hier im Forum). Wie und wo muss ich nun die Überprüfung der Benutzerrechte einbauen?

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 19.03.2010, 18:51:57

Hallo Andreas,
Obwohl es wohl keinem der gängigen Entwurfsmethoden entspricht
Welches Pattern hättest du erwartet? In Möglichkeit 1 ist es der DataMapper, in 2 der DataMapper + dem Domain Object Pattern - jeweils in einer generischen (usermanagement) und einer expliziten Form (guestbook2009). Oder was meintest du?
Wie und wo muss ich nun die Überprüfung der Benutzerrechte einbauen?
Ich würde das in der darstellenden Komponente tun, sprich im Document-Controller. Dort hast du das User-Objekt und kannst den UmgtManager fragen, welche (Funktions-)Rechte (=Permissions) der Benutzer hat. Sofern das erwartete enthalten ist, wird der Menüpunkt dargestellt, falls nicht, dann nicht. Ob das im konkreten die PN-Funktion sein soll, definierst du am besten im Umgt-Backend über eine Permission. Diese ist einem Permission-Set zugewiesen das wiederum einer Rolle zugeordnet ist. Die Rolle gibst du dann dem Benutzer und der darf dann die PN-Funktion ausführen oder eben nicht.

Die PN-Funktion selbst bindest du dann in den Content-Bereich per Tag ein (hierfür hast du ja ein eigenes Modul). Den Benutzer kannst du wie oben beschrieben in der Session speichern und in den Modulen jeweils auslesen. Wichtig hierbei ist nur, dass du den selben Namespace beim Erzeugen des SessionManager angibts, sonst findest du im einen oder anderen Bereich den User nicht. ;)
Viele Grüße,
Christian

Avedo

Re: Modul pmessage

Beitrag von Avedo » 19.03.2010, 22:22:15

Guten Abend!
Welches Pattern hättest du erwartet? ... Oder was meintest du?
Entschuldige... ich meinte damit mein unkonventionelles Vorgehen bei der Implementierung.

Mich würde noch interessieren, ob bzw. wie es möglich ist, zu überprüfen, ob ein Benutzer angemeldet ist. Denn im Falle des PN-Moduls reicht es ja, wenn Benutzer angemeldet sind, um diesen Service verwenden zu können. Oder wäre das zu unsauber?

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 20.03.2010, 01:20:19

Hallo Andreas,

entschuldigen brauchst du dich für nichts. Mir war nur nicht klar, was du meintest. Und: ich bin sicher nicht unfehlbar, es hätte mir auch etwas entgehen können. ;)
Mich würde noch interessieren, ob bzw. wie es möglich ist, zu überprüfen, ob ein Benutzer angemeldet ist. Denn im Falle des PN-Moduls reicht es ja, wenn Benutzer angemeldet sind, um diesen Service verwenden zu können. Oder wäre das zu unsauber?
Ich würde das so implementieren, dass der Benutzer in der Session vorhanden sein muss. Hierfür würde ich ein ganz bestimmtes Attribut in der Session nutzen - z.B. loggedinuser. Enthält dieses den Wert null ist der Benutzer nicht eingeloggt, enthält es ein User-Objekt, passt alles. Das ist sicherheitstechnisch sicher nicht die beste Implementierung, sollte aber zunächst ausreichen.
Viele Grüße,
Christian

Avedo

Re: Modul pmessage

Beitrag von Avedo » 22.03.2010, 19:07:43

Hallo Christian,

Ich habe mich eben noch ein bisschen mit dem PN-Modul beschäftigt und habe mir die Frage gestellt, wieso im Beispiel des Gästebuchs so kompliziert gearbeitet wird. In der Variante, die ohne den generischen O/R-Mapper arbeitet, kann ich das ja noch nachvollziehen, aber wieso werden zum Beispiel die Domänen-Objekte im Modul guestbook2009 so umständlich implementiert? Das geht doch einfacher. Der Mapper lässt sich ohne diese speziell definierten Domänen-Objekte auch schneller implementieren. Des leichteren Verständnisses wegen, habe ich mal den MessageMapper, so wie ich ihn mir vorstelle umgesetzt.

Code: Alles auswählen

<?php


   import('modules::genericormapper::data', 'GenericORMapperFactory');

	import('modules::pmessage::biz', 'Message');



	/**

	 * @package modules::pmessage::data

	 * @class MessageMapper

	 *

	 * DataMapper of the private
	 * message manager modul.

	 *

	 * @author Andreas Wilhelm

	 * @version

	 * Version 0.1, 22.03.2010<br />

	 */

	class MessageMapper extends APFObject {

      /**
       * The GenericORMapper object.
       * @var GenericORMapper
       */
      private $_orm;

		/**
		 * @public
		 *
		 * The default constructor loads the GenericORMapper.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
       */
		public MessageMapper($user) {

			// Load the datamapper service object ...
			$ormf = &$this->__getServiceObject('modules::genericormapper::data','GenericORMapperFactory');

			// ... and load the mapper with the basic configuration.
			$this->_orm = &$ormf->getGenericORMapper('modules::pmessage', 'pmessage_1', 'pmessage'); 
		}
      
		/**
		 * @public
		 *
		 * Loads the list of messages.
		 *
		 * @return GenericDomainObject[] A list of all messages.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
       */
		public function loadMessageList() {

			// Create the statement to select the desired messages ...
			$select = '
				SELECT 
					* 
				FROM 
					ent_pn 
				ORDER BY 
					CreationTimestamp DESC;';

			// ... and load the list of messages. 
			$msgList = $this->_orm->loadObjectListByTextStatement('Message', $select);

			return $msgList;
      }

		/**
		 * @public
		 *
		 * Loads a list of messages received by a specified user.
		 *
		 * @param User $usr The user's domainobject.
		 * @return GenericDomainObject[] A list of all messages received by the user.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
		 */
      public function loadReceivedMessages($usr) {

			// Create the statement to select the desired messages ...
			$select = '
				SELECT 
					* 
				FROM 
					ent_pn 
				WHERE 
					Receiver = \'' . $usr->getProperty('UserID');  . '\' 
				ORDER BY 
					CreationTimestamp DESC;';

			// ... and load the list of messages. 
			$msgList = $this->_orm->loadObjectListByTextStatement('Message', $select);
         
			return $msgList;
		}

		/**
		 * @public
		 *
		 * Loads a list of messages sentby a specified user.
		 *
		 * @param User $usr The user's domainobject.
		 * @return GenericDomainObject[] A list of all messages sent by the user.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
		 */
      public function loadSentMessages($usr) {

			// Create the statement to select the desired messages ...
			$select = '
				SELECT 
					* 
				FROM 
					ent_pn 
				WHERE 
					Sender = \'' . $usr->getProperty('UserID');  . '\' 
				ORDER BY 
					CreationTimestamp DESC;';

			// ... and load the list of messages. 
			$msgList = $this->_orm->loadObjectListByTextStatement('Message', $select);
         
			return $msgList;
		}

		/**
		 * @public
		 *
		 * Loads a single message.
		 *
		 * @param int $id The id of the message.
		 * @return GenericDomainObject The desired message.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
		 */
      public function loadMessageById($id) {

			// Create the statement to select the desired messages ...
			$select = '
				SELECT 
					* 
				FROM 
					ent_pn 
				WHERE 
					MessageID = \'' . $id . '\' 
				ORDER BY 
					CreationTimestamp DESC;';

			// ... and load the message. 
			$msg = $this->_orm->loadObjectByTextStatement('Message', $select);
         
			return $msg;
		}

		/**
		 * @public
		 *
		 * Saves the new / edited message.
		 *
		 * @param GenericDomainObject $msg The message to save.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
		 */
		public function saveMessage($msg) {

			// Save the given message using the or-mapper.
			$this->_orm->saveObject($msg);
		}

		/**
		 * @public
		 *
		 * Deletes the given message from the database.
		 *
		 * @param GenericDomainObject $msg The message to delete.
		 *

		 * @author Andreas Wilhelm

		 * @version

		 * Version 0.1, 22.03.2010<br />
		 */
		public function deleteMessage($msg) {

			// Delete the given message using the or-mapper.
			$this->_orm->saveObject($msg);
		}

	}

?>
Du siehst ich verwende direkt das GenericDomainObject. So erspare ich mir das hin und her kopieren irgendwelcher Inhalte. Möchte ich dennoch ein Message und ein User Objekt für eine schönere Signatur der einzelnen Methoden verwenden, so könnte ich einfach das DomainObject wrappen. Nachfolgend ein Beispiel, wie ich es machen würde.

Code: Alles auswählen

/**

 * @package modules::pmessage::biz

 * @class Message

 *

 * DataMapper of the private
 * message manager modul.

 *

 * @author Andreas Wilhelm

 * @version

 * Version 0.1, 22.03.2010<br />

 */

class Message extends GenericDomainObject {
   /**
    * @public
    *
    * The default constructor loads calls the constructor
    * of the parent  GenericDomainObject class.
    *
    * @author Andreas Wilhelm

    * @version

    * Version 0.1, 22.03.2010<br />
    */
   public Message() {
      // Call the parent constructor.
      parent::__construct('Message');
   }
}
Das sollte ja so funktionieren. Was meinst du zu diesem Ansatz. Finde ihn deutlich schöner.

Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 22.03.2010, 22:23:52

Hallo Andreas,
In der Variante, die ohne den generischen O/R-Mapper arbeitet, kann ich das ja noch nachvollziehen, aber wieso werden zum Beispiel die Domänen-Objekte im Modul guestbook2009 so umständlich implementiert? Das geht doch einfacher
Hier wird zum einen die Datenhaltung gegen die Anwendung abstrahiert und zum anderen wird das Domänen-Modell genutzt um die Mehrsprachigkeit transparent für die Anwendung abzubilden. Würde das nicht so implementiert werden, müsste die Anwendung mit den generischen Attribut-Objekten in der GUI hantieren, was wirklich umständlich ist. So hast du ein domain object, das sich über die Sprache hinweg identisch verhält.
Das bedeutet aber nicht, dass du das immer auch so für deine Applikationen nutzen musst. Oft ist das auch garnicht notwendig, weil Mehrsprachigkeit oder dergleichen nicht relevant sind.
Des leichteren Verständnisses wegen, habe ich mal den MessageMapper, so wie ich ihn mir vorstelle umgesetzt.
Passt. Ein paar Hinweise:
  • Bei loadMessageList() könntest du auch einfach loadObjectListByCriterion() mit einem entsprechenden GenericCriterionObject nutzen.
  • loadReceivedMessages($usr) ist inkonsistent, da du den Manager ja bereits mit dem User als Konstruktor-Argument erzeugst. Also entweder die Signaturen immer mit dem User als Argument oder nur im Konstruktor.
Das sollte ja so funktionieren. Was meinst du zu diesem Ansatz.
Das funktioniert sicher, aber ich würde das via decorator (siehe oben) lösen, das ist intuitiver und die API ist lesbarer, wenn du getMessage() statt getProperty('Message') hast.
Viele Grüße,
Christian

Avedo

Re: Modul pmessage

Beitrag von Avedo » 08.04.2010, 21:55:07

Guten Abend!

Habe entgegen meiner guten Vorsätze nun doch noch etwas an diesem Modul gearbeitet. Habe soeben das Benutzer-Domänen-Objekt implementiert, dass das generische Domänen-Objekt kapselt. Da der Postman oder auch die Postbox, wie man es auch nennen möchte, keine Daten des Benutzers ändern sollte, habe ich auf die Setter-Methoden einfach verzichtet. Ist das denn nun so ok oder ist das eher weniger im Sinne des Erfinders?

Code: Alles auswählen

<?php

/**
 * @package modules::pmessage::biz

 * @class User

 *

 * Capsulates the GenericDomainObject of a user so that it can be used
 * with the private user message modul. For this reason it does not implement
 * any setter methods, because there is no reason why a postbox should rename a 
 * user, so do not give it the change to do so.
 *
 * @author Andreas Wilhelm
 * @version
 * Version 0.1, 08.04.2010<br />
 */
class User {

    /**
     * @private
     * The generic user domain object.
     */
    private $user;

    /**
     * @public
     *
     * The default constructor that receives the GenericDomainObject 
     * that should be capsulated.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 08.04.2010<br />
     */
    public function User(GenericDomainObject $user = null) {

        if($user == null){
            $this->user = new GenericDomainObject('User');
        }

        else {
            $this->user = $user;
        }
    }

    /**
     * @public
     *
     * Returns the id of the user.
     *
     * @return The user's id.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getUserID(){
        return $this->user->getProperty('UserID');
    }

    /**
     * @public
     *
     * Returns the name of the user.
     *
     * @return The user's name.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getUsername(){
        return $this->user->getProperty('Username');
    }

    /**
     * @public
     *
     * Returns the name of the user to be displayed.
     *
     * @return The user's name to be displayed.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getDisplayName(){
        return $this->user->getProperty('DisplayName');
    }

    /**
     * @public
     *
     * Returns the first name of the user.
     *
     * @return The user's first name.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getFirstName(){
        return $this->user->getProperty('FirstName');
    }

    /**
     * @public
     *
     * Returns the last name of the user.
     *
     * @return The user's last name.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getLastName(){
        return $this->user->getProperty('LastName');
    }

    /**
     * @public
     *
     * Returns the generic domain object capsulated by this class.
     *
     * @return The generic domain object.
     *
     * @author Andreas Wilhelm
     * @version
     * Version 0.1, 18.03.2010
     */
    public function getExternalRepresentation() {
        return $this->user;
    }
}
Liebe Grüße,

Andreas

Benutzeravatar
dr.e.
Administrator
Beiträge: 4537
Registriert: 04.11.2007, 16:13:53

Re: Modul pmessage

Beitrag von dr.e. » 09.04.2010, 09:48:34

Hallo Andreas,
Ist das denn nun so ok oder ist das eher weniger im Sinne des Erfinders?
Gut so! :)
Viele Grüße,
Christian

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast