You are not logged in.

[Benutzernachrichtensystem] Einige Fragen (Entwickler)

Dear visitor, welcome to Packageforge. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

1

Friday, March 2nd 2012, 4:56pm

Einige Fragen (Entwickler)

Hallo,
ich würde dein Plugin gerne zu meinem What's Up?-Plugin hinzufügen. Leider verstehe ich noch nicht ganz, welche Dateien alles nötig sind, damit die Benachrichtigungen funktionieren.

Wenn nun ein Benutzer einen Eintrag liked (Funktion meines Plugins), würde ich gern eine Benachrichtigung abfeuern. Dazu habe ich mir erstmal eine notificationevent.xml erstellt:

XML

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="http://www.woltlab.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.woltlab.com/XSD/notification-event.xsd">
	<import>
		<event>
			<name>like</name>
        	<objecttype>whatsUpEntry</objecttype>
			<classfile>lib/data/user/notification/event/DefaultNotificationEvent.class.php</classfile>
        	<languagecategory>wcf.whatsUp.notification</languagecategory>
        	<defaultnotificationtype>userMessages</defaultnotificationtype>
        	<icon>add</icon>
		</event>
	</import>
</data>


Nun habe ich einen Eventlistener auif executed@WhatsUpLikeAction gesetzt und dort folgenden Code benutzt:

PHP Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
require_once(WCF_DIR.'lib/system/event/EventListener.class.php');
require_once(WCF_DIR.'lib/data/user/notification/NotificationHandler.class.php');
/**
 * @author     Christopher Walz (kifferkniffer)
 * @license    http://forum.cwalz.de/index.php?page=TermsOfLicense
 * @package    de.cwalz.whatsUp
 */
class WhatsUpNotificationListener implements EventListener {
    public function execute($eventObj$className$eventName) {
        switch($className) {
            case 'WhatsUpLikeAction':
                NotificationHandler::fireEvent('like''whatsUpEntry'11); // die Zahlen sind nur zum Testen da
            break;
        }
    }    
    
}

?>


Es gibt kein Fehler, aber auch keine Benachrichtigung.

Edit: Okay, ich hatte vergessen die notificationevent.xml zu installieren ;) Jetzt erhalte ich auf jeder Seite des Forums folgenden Fehler:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
		Fatal error: PHP notice in file 
D:\xampp\htdocs\forum\wcf\lib\data\user\notification\NotificationHandler.class.php
 (422): Undefined index: object
	
		
			
						
			Information:
			
				error message: PHP notice in file 
D:\xampp\htdocs\forum\wcf\lib\data\user\notification\NotificationHandler.class.php
 (422): Undefined index: object

				error code: 0
				
								file: D:\xampp\htdocs\forum\wcf\lib\system\WCF.class.php (281)

				php version: 5.3.5

				wcf version: 1.1.8 (Tempest)

				date: Fri, 02 Mar 2012 16:00:25 +0000

				request: /forum/index.php?form=UserProfileEdit

				referer: 

			
			
			Stacktrace:
			#0 D:\xampp\htdocs\forum\wcf\lib\data\user\notification\NotificationHandler.class.php(422): WCF::handleError(8, 'Undefined index...', 'D:\xampp\htdocs...', 422, Array)
#1 D:\xampp\htdocs\forum\wcf\lib\data\user\NotificationUser.class.php(111): NotificationHandler::getAvailablePackageIDs()
#2 D:\xampp\htdocs\forum\wcf\lib\system\event\listener\StructuredTemplateUserMessagesNotificationListener.class.php(26): NotificationUser->hasOutstandingNotifications()
#3 D:\xampp\htdocs\forum\wcf\lib\system\event\EventHandler.class.php(207): StructuredTemplateUserMessagesNotificationListener->execute(Object(StructuredTemplate), 'StructuredTempl...', 'shouldDisplay')
#4 D:\xampp\htdocs\forum\wcf\lib\system\template\Template.class.php(255): EventHandler::fireAction(Object(StructuredTemplate), 'shouldDisplay')
#5 D:\xampp\htdocs\forum\wcf\lib\page\AbstractPage.class.php(100): Template->display('userProfileEdit')
#6 D:\xampp\htdocs\forum\wcf\lib\form\UserProfileEditForm.class.php(177): AbstractPage->show()
#7 D:\xampp\htdocs\forum\wcf\lib\page\AbstractPage.class.php(46): UserProfileEditForm->show()
#8 D:\xampp\htdocs\forum\wcf\lib\util\RequestHandler.class.php(64): AbstractPage->__construct()
#9 D:\xampp\htdocs\forum\wcf\lib\util\RequestHandler.class.php(95): RequestHandler->__construct('UserProfileEdit', Array, 'form')
#10 D:\xampp\htdocs\forum\index.php(8): RequestHandler::handle(Array)
#11 {main}


Was mit auffällt:
In den Benachrichtigungseinstellungen gibt es keine Option zu meiner Benachrichtigung, wie füge ich diese hinzu? Welche Datei fehlt mir noch, damit die Benachrichtigung ankommt?

Gruß und danke schonmal :)

This post has been edited 1 times, last edit by "kifferkniffer" (Mar 2nd 2012, 5:02pm)


Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

2

Friday, March 2nd 2012, 5:30pm

Hallo,
Leider verstehe ich noch nicht ganz, welche Dateien alles nötig sind, damit die Benachrichtigungen funktionieren.
ein guter Anhaltspunkt ist das Plugin zur Gästebuchbenachrichtigung: WoltLab® - Plugin-Store - Gästebuchbenachrichtigungen
Nun habe ich einen Eventlistener auif executed@WhatsUpLikeAction gesetzt und dort folgenden Code benutzt:
Willst du die Benachrichtigungen als optionales Plugin einbinden, oder direkt in dein Paket? Wenn letzteres der Fall ist, dann brauchst du keinen EventListener, sondern kannst das Event direkt in deiner Action auslösen. Die Eventlistener verwende ich nur, da ich WoltLabs Pakete ja erweitern muss.

Was du offenbar komplett vergessen hast und weshalb es auch Fehler hagelt, ist dein NotificationObject/NotificationObjectType bereit zu stellen. Was diese Klassen können müssen, siehst du an diesen beiden Interfaces. Als Beispiel kannst du wieder beim Gästebuchbenachrichtigungsplugin gucken.

Falls dir das zu allgemein ist und du detaillierter wissen musst, wie die Implementierungen aussehen, kann ich dir sonst nochmal ein paar Coderümpfe zeigen.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

3

Friday, March 2nd 2012, 5:35pm

Ich würde das gerne direkt einbauen, da es doch ziemlich wichtig ist und perfket zum Plugin passt.
NotificationHandler:fireEvent() bzw. revokeEvent() dann einfach direkt in der WhatsUpLikeAction bzw. WhatsUpUnLikeAction-Klasse einbinden?

Ich schau mir die NotificationObjekte mal an, vielen Dank. Falls ichs nicht hinbekomme, melde ich mich nochmal :)

Edit: Achja

Quoted

In den Benachrichtigungseinstellungen gibt es keine Option zu meiner Benachrichtigung, wie füge ich diese hinzu?

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

4

Friday, March 2nd 2012, 5:50pm

Sofern du das richtig implementierst (insbesondere müssen dazu die NotifcationObjects ersteltl und per PIP registriert werden, siehe Gästebuch), dann wird die Option automatisch erstellt und angezeigt.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

5

Friday, March 2nd 2012, 6:26pm

Hi,
funktioniert jetzt fast alles, bis auf:
- Die Sprachvariablen (muss ich natürlich noch machen ;))
- Unter den Benachrichtigungseinstellungen sind alle checkboxes disabled (siehe Bild)
- und daraus folgt wohl auch der "Fehler", dass keine Infobox bei einer neuen Benachrichtigung angezeigt wird, sondern nur im Header bei "Benachrichtigungen (1)" steht


Gruß
kifferkniffer has attached the following image:
  • localhost screen capture 2012-3-2-18-24-58.png

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

6

Friday, March 2nd 2012, 7:05pm

Mach einfach die Sprachvariablen, dann sollten sich dadurch automatisch Fehler 2 und 3 lösen ;)

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

7

Friday, March 2nd 2012, 7:40pm

Habe nun folgende Sprachvariablen hinzugefügt:

XML

1
2
3
4
5
6
7
8
9
 <category name="wcf.user.notification">
		<item name="wcf.user.notification.object.type.whatsUpEntry"><![CDATA[What's Up]]></item>
     </category>
	 
	<category name="wcf.whatsUp">
		 <item name="wcf.whatsUp.notification.like.title"><![CDATA[Neues "Like"]]></item>
		 <item name="wcf.whatsUp.notification.like.description"><![CDATA[Sie erhalten eine Benachrichtigung, wenn jemand Ihren Status liked.]]></item>
		 <item name="wcf.whatsUp.notification.like"><![CDATA[{if $event->getObject()->userID}<a href="index.php?page=User&amp;userID={@$event->getObject()->userID}{@SID_ARG_2ND}">{$event->getObject()->username}</a>{/if} gefällt Ihr <a href="{@$event->getObject()->getURL()}{@SID_ARG_2ND}">What's Up?-Eintrag</a>.]]></item>
     </category>


Sie werden auch alle korrekt umgewandelt, trotzdem besteht Problem 2 und 3 noch. Fehlen da noch welche, damit es richtig funktioniert? Problem 2 und 3 sollten doch eigentlich nicht von den Sprachvariablen abhängig sein?

Gruß und danke!

Edit: Hmm komisch, warum wird der XML-Syntag hier als Fehlerhaft dargestellt? Bei der Installation gibt es keine Fehler.

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

8

Friday, March 2nd 2012, 8:00pm

Edit: Hmm komisch, warum wird der XML-Syntag hier als Fehlerhaft dargestellt? Bei der Installation gibt es keine Fehler.
Der BBCode scheint sich an dem Hochkomma zu stören: What's Up. Dafür ist aber eigentlich der CDATA Block da.

Ja es fehlen noch welche. Und zwar die verschiedenen für die einzelnen Benachrichtigungstypen. Siehe Gästebuch. Es fehlt:

wcf.whatsUp.notification.like.short
wcf.whatsUp.notification.like.medium

wcf.whatsUp.notification.like.userMessages

wcf.whatsUp.notification.like.mail

wcf.whatsUp.notification.like.pm

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

9

Friday, March 2nd 2012, 8:14pm

Vielen Dank, funktioniert nun alles! Super Support :)
Noch eine Frage: Wann kommen die short, medium und userMessages Sprachvariablen zum Einsatz?

Gruß

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

10

Friday, March 2nd 2012, 8:17pm

userMessages kommt zum Einsatz, wenn eben die blaue Infobox dargestellt wird bzw. vom Nutzer verwendet wird. short und medium sind kürzere Strings der Nachricht. Short kommt beispielsweise als Mailtitel zum Einsatz, wobei HTML gestrippt wird.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

11

Friday, March 2nd 2012, 8:53pm

Danke!
Noch eine Frage ;)
Im Header das "Benachrichtigungen (1)" wird die Anzahl (also die Nummer in Klammern gecached?).
Ich habe eine Benachrichtigung, aber diese habe ich bereits gelesen (ist auch nicht mehr fett gedruckt), aber die (1) will einfach nicht verschwinden :?

Edit: Nach dem Ausloggen & Einloggen ist sie weg. Also doch Cache?

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

12

Friday, March 2nd 2012, 9:15pm

Hallo,

ja das wird gecached. Sollte sich aber beim Bestätigen der Benachrichtigung oder dem Aufrufen der Auflistung der Benachrichtigungen resettet werden.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

13

Friday, March 2nd 2012, 10:25pm

Ja, war wohl ein Einzelfall. Noch eine Frage:
Wie kann ich in den Sprachvariablen auf die $additionalData zugreifen, die ich hier mitgebe:

PHP Source code

1
NotificationHandler::fireEvent('comment''whatsUpEntry'$this->whatsUpID$this->ownerID, array('comment' => $this->comment'userID' => WCF::getUser()->userID'username' => WCF::getUser()->username));


Danke

Habs schon gefunden, additionalData Array ;)

This post has been edited 1 times, last edit by "kifferkniffer" (Mar 2nd 2012, 10:48pm)


  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

14

Saturday, March 3rd 2012, 12:34am

Ich muss leider doch nochmals stören ;)
Ich würde nun gerne die passenden Benachrichtigungen entfernen, sobald der Benutzer die Seite (WhatsUpConversationPage) aufruft. Dazu habe ich in der Klasse folgenden Code hinzugefügt (inspiriert aus deinem GuestbookNotification-Package):

PHP Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
                        // clear notification
                         if (WCF::getUser()->userID) {
                            $userIDScope = array(WCF::getUser()->userID);
                            $objectIDScope = array($this->whatsUpID);

                            $user = new NotificationUser(nullWCF::getUser(), false);
                            $objectTypeObject NotificationHandler::getNotificationObjectTypeObject('whatsUpEntry');
                            if (isset($user->notificationFlags[$objectTypeObject->getPackageID()]) && $user->notificationFlags[$objectTypeObject->getPackageID()] > 0) {
                                $count NotificationEditor::markConfirmedByObjectVisit($user->userID, array('like''comment'), 'whatsUpEntry'$objectIDScope);
                                $user->removeOutstandingNotification($objectTypeObject->getPackageID(), $count);
                            }
                                        
                        }


Die Benachrichtigungen werden auch gelöscht, jedoch werden leider auch die gelöscht, die ungelesen sind.
Beispiel:
User1 hat zwei Beiträge, WhatsUpConversationPage&id=1 und WhatsUpConversationPage&id=2.
User2 liked Beitrag 1 auf der Seite WhatsUpConversationPage&id=1.
Use 3 liked Beitrag 2 auf der Seite WhatsUpConversationPage&id=2.

Jetz hat User1 zwei Benachrichtigungen. Soweit stimmt alles. Nun ist aber egal, welche Seite User1 aufruft (id1 oder id2), es werden immer beide Benachrichtigungen gelöscht. Kann man der Methode removeOutstandingNotification() nicht irgendwie eine NotificationID mitgeben, sodass nicht gleich alle gelöscht werden?

Vielen Dank!

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

15

Saturday, March 3rd 2012, 11:56am

Der Komfort der Funktion ist ja gerade, dass du nur angeben musst, welche events und welche scopes an Objekten. Wenn die Benachrichtigungen zu mehreren whatsUpEntries als bestätigt markiert werden, dann sind deren objectIDs wohl auch in dem Array objectIDScope. So ganz hast du dich da auch nicht an die Vorlage gehalten. Ich gehe jetzt mal davon aus, dass du das im WCF übliche DatabaseObject Design verwendest, dann müsste der Code ungefähr so aussehen:

PHP Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
                                if (WCF::getUser()->userID) {
                                        // determine users which might be affected by confirmations
                                        $userIDScope = array($eventObj->frame->getUserID()); // dein plugin liegt im profil, also müsste es eine UserProfileFrame geben
                                        $objectIDScope = array();
                                        foreach ($eventObj->entryList->getObjects() as $entry) { // durchläuft alle whatsUpEntries deiner DBOList und fügt sie in den user Scope hinzu, falls sie einen Kommentar haben bzw. in den object scope, falls sie überhaupt existent sind ;) Damit enthält nun objectIDScope ALLE whatsUp Einträge, die auf der aktuellen Seite angezeigt werden. Nicht mehr und nicht weniger. Wenn deine DBOList mehr Einträge enthält ist dein Klassendesign irgendwie falsch.
                                                if ($entry->commentTime 0) {
                                                        $userIDScope[] = $entry->userID;
                                                }
                                                $objectIDScope[] = $entry->entryID;
                                        }
                                        if (count($objectIDScope) && in_array(WCF::getUser()->userID$userIDScope)) { // ist der aktuelle user im Scope der Beiträge bzw. Benutzer, die auf dieser Seite eventuell eine Benachrichtigung erhalten haben?
                                                $user = new NotificationUser(nullWCF::getUser(), false);
                                                $objectTypeObject NotificationHandler::getNotificationObjectTypeObject('whatsUpEntry');
                                                if (isset($user->notificationFlags[$objectTypeObject->getPackageID()]) && $user->notificationFlags[$objectTypeObject->getPackageID()] > 0) {
                                                        $count NotificationEditor::markConfirmedByObjectVisit($user->userID, array('like''comment'), 'whatsUpEntry'$objectIDScope);
                                                        $user->removeOutstandingNotification($objectTypeObject->getPackageID(), $count);
                                                }
                                        }
                                }


So müsste das grob aussehen. Die Details hängen natürlich von deiner genauen Implementierung ab und wie sehr du dich an das DBO Design gehalten hast. Das Benutzernachrichtensystem ist zugegebenermaßen recht steif darauf ausgelegt, dass dieses strikt eingehalten wurde.

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

16

Saturday, March 3rd 2012, 12:34pm

Hi,
ich würde die Benachrichtigung gerne nur entfernen, wenn jemand auf diese Seite geht und nicht auf diese
Da es auf dieser Seite ja nur eine Whats Up ID (und Eintrag gibt), habe ich die foreach-Schleife entfernt.
Also einfach nur

PHP Source code

1
2
3
                                        if ($entry->commentTime 0) {
                                                        $userIDScope[] = $entry->userID;
                                                }

für den einen Eintrag kontrollieren?

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

17

Saturday, March 3rd 2012, 12:50pm

Achso, also nur ein einziger Eintrag auf der Seite? Das ist dann doch recht einfach.

PHP Source code

1
2
3
4
5
6
7
8
9
// angenommen dein entry heißt $entry ;)
if ($entry->userID == WCF::getUser()->userID) { // ist der aktuelle user der "besitzer" des eintrags?
    $user = new NotificationUser(nullWCF::getUser(), false);
    $objectTypeObject NotificationHandler::getNotificationObjectTypeObject('whatsUpEntry');
    if (isset($user->notificationFlags[$objectTypeObject->getPackageID()]) && $user->notificationFlags[$objectTypeObject->getPackageID()] > 0) {
        $count NotificationEditor::markConfirmedByObjectVisit($user->userID, array('like''comment'), 'whatsUpEntry'$entry->entryID);
        $user->removeOutstandingNotification($objectTypeObject->getPackageID(), $count);
    }
}

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

18

Saturday, March 3rd 2012, 3:32pm

Funktioniert leider nicht so wie es soll:
Auf dem Bild sind zwei Benachrichtigungen, einmal von einem neuen Kommentar für WhatsUpID 2 und einmal für WhatsUpID 3. Wenn ich nun auf eine klicke (egal welche), dann löscht er mir die andere auch aus den userMessages und oben aus dem Header (Statt "Benachrichtigungen (2)" steht nach dem Klick "Benachrichtigungen").
Wenn ich jedoch drauf klicke ist die andere Benachrichtigung noch fettgedruckt, also ungelesen. Es wird also nur aus der userMessage und dem Header fälschlicherweise entfernt.
Der Code sieht so aus:

PHP Source code

1
2
3
4
5
6
7
8
                        if ($this->entries['userID'] == WCF::getUser()->userID) { // ist der aktuelle user der "besitzer" des eintrags?
                            $user = new NotificationUser(nullWCF::getUser(), false);
                            $objectTypeObject NotificationHandler::getNotificationObjectTypeObject('whatsUpEntry');
                            if (isset($user->notificationFlags[$objectTypeObject->getPackageID()]) && $user->notificationFlags[$objectTypeObject->getPackageID()] > 0) {
                                $count NotificationEditor::markConfirmedByObjectVisit($user->userID, array('like''comment'), 'whatsUpEntry', array($this->entries['whatsUpID']));
                                $user->removeOutstandingNotification($objectTypeObject->getPackageID(), $count);
                            }
                        }


Vielen Dank für dein Support :)
kifferkniffer has attached the following image:
  • localhost screen capture 2012-3-3-15-30-24.png

Hawkes

Administrator

(800)

Posts: 3,296

Location: Konstanz

Occupation: Student

Reputation modifier: 13

  • Send private message

19

Saturday, March 3rd 2012, 4:49pm

Bevor ich jetzt weiter verwirrt bin, eine Frage zu deinem Code-Design: Ist 'whatsUpID' der eindeutige Bezeichner einer einzelnen Nachricht? Also sowas wie eine entryID?

  • "kifferkniffer" started this thread

Posts: 22

Reputation modifier: 4

  • Send private message

20

Saturday, March 3rd 2012, 5:02pm

Genau so ist es. Ich hätte den Code vllt doch mehr auf das WCF Design aufbauen sollen ;)