Durchsuchbare Dokumentation aufrufen | Zurück zur Dokumentationsübersicht
Navigation: Dokumentationen agorum core > agorum core JavaScript-API
Mit dieser Bibliothek und den enthaltenen Funktionen können Sie Objekte:
let objects = require('common/objects');
Der Rückgabewert "Objekt" meint immer den Typ "GlobalObject". Die Dokumentation dazu finden Sie unter GlobalObject.
Im Standard verwendet das System die Sitzung des eingeloggten Benutzers. Eine hiervon abweichende Sitzung können Sie wie in der Dokumentation zu SessionController(sc) beschrieben verwenden.
Diese Funktionen finden Objekte.
Syntax
objects.find('<id>') objects.tryFind('<id>')
Es werden alle Arten von IDs unterstützt, die auch die agorum API akzeptiert, unter anderem:
9999
550e8400-e29b-11d4-a716-446655440000
/agorum/roi/Files
, home:MyFiles/Test
, relative:12345/Sub
user:roi
, group:GRP_Demo, acl:ACL_Demo, pai:AclList
Der Unterschied zwischen find()
und tryFind()
besteht darin, dass Erstere einen Fehler wirft, wenn das Objekt nicht gefunden wird, während Letztere null
zurück gibt.
Beispiel
// Homeordner des Users und darunter den Ordner MyFiles let home = objects.find('home:MyFiles'); // Homeordner des Users und darunter den Ordner MyFiles/Test let homeTest = objects.find('home:MyFiles/Test'); // Object mit der id 9999 let root = objects.find('9999'); // Benutzer roi let user = objects.find('user:roi'); // PAI holen let pai = objects.find('pai:AclList');
Ergebnis
Sie erhalten bei beiden Funktionen ein Objekt vom Typ "GlobalObject" zurück.
Sie können beim Holen eines Pfades den Pfad gleich anlegen lassen. Ist der Pfad noch nicht vorhanden, wird dieser angelegt, ansonsten wird er zurückgegeben, wie beim normalen find
auch.
Zu beachten ist, dass auf diese Weise nur Ordner angelegt werden können, es dürfen beim find
also auch nur Ordner angegeben sein. Die Berechtigung wird vom übergeordneten Ordner vererbt. Der User ist der User, mit dessen Session der find
-Befehl aufgerufen wird.
Bevor Sie diese Funktion nutzen, überlegen Sie sich, in welchem Bereich Sie diesen Ordner anlegen wollen. Ihnen stehen die Benutzerbereiche und der Root Ordner zur Verfügung.
Benutzerbereich
Jeder User in agorum core besitzt einen Benutzerbereich. In diesem liegen seine "Eigenen Dateien" oder auch benutzerspezifische Einstellungen, wie Einstellungen der Suche oder gesetzte Filter. Sie als Entwickler werden diesen Benutzerbereich vermutlich nie oder kaum nutzen.
So finden Sie den Benutzerbereich:
Haben Sie etwa eine eigene Oberfläche erstellt, in der Sie Ihren Anwendern ermöglichen, Einstellungen zur Darstellbarkeit vorzunehmen, dann speichern Sie diese in den Benutzerbereich des angemeldeten Users ab. Hierzu können Sie Ordner mit dem folgenden Befehl erstellen:
let o1 = objects.find('home:Testordner/Unterordner:create');
Das Synonym home: steht für den Bereich:
home/<angemeldeter user> //Im Beispiel des Screenshots: Home/demo
Möchten Sie direkt in den "Eigenen Dateien" des angemeldeten Users einen Ordner anlegen, nutzen Sie folgenden Befehl:
let o2 = objects.find('home:myFiles/Testordner unter Eigene Dateien:create');
Der Vorteil bei der Nutzung von home: liegt auf der Hand: Sie müssen nicht den kompletten Pfad zusammenbasteln, sondern können anhand von diesem Kürzel direkt auf den Benutzerbereich des angemeldeten Users zugreifen.
Root-Ordner
In einem Root-Ordner liegen alle Dateien / Objekte, einschließlich des Benutzerbereiches, die sich nicht im Serverpapierkorb befinden.
Sie haben hier Zugriff auf den Benutzerbereich sowie den Dateien des Systems, müssen allerdings den kompletten Pfad kennen, in dem Sie Ordner erstellen möchten:
let o1 = objects.find('relative:9999/Testordner/Unterordner:create');
Dieser Befehl erstellt folgende Ordnerstruktur:
Die Option "create" in der Funktion "find" bietet sich immer dann an, wenn Sie mehrere Ordner, also eine Ordnerstruktur, anlegen möchten. Möchten Sie nur einen einzigen Ordner erstellen, können Sie dies auch so umsetzen:
<parentpath>.createPath("<New Folder>")
Achtung: Beeinträchtigung der Systemleistung durch Aufruf. Dieser Aufruf ist nicht für große Ergebnismengen oder Objekte mit Unterobjekten geeignet. Führen Sie ihn nur für einfache Suchanfragen aus. Nutzen Sie für große Ergebnismengen die Funktion query.
Diese Funktion führt eine einfache Suchanfrage aus, die sowohl Lucene als auch Solr als Back-end unterstützt.
Syntax
let objArr = objects.search('<query>')
Ergebnis
Sie erhalten ein Array mit Objekten zurück.
Hinweis: Funktioniert nur mit Solr als Backend. Achten Sie auf die korrekte Solr-Syntax.
Diese Funktion führt eine erweiterte Suchanfrage aus. Damit verarbeiten Sie durch zusätzliche Möglichkeiten bei Sortierung, Limitierung und Paging auch beliebig große Ergebnismengen. Durch die Verwendung von Objektattributen aus dem Index erzielen Sie zudem eine höhere Performance, da keine Datenbankzugriffe stattfinden müssen. Außerdem sind durch Faceting auch tiefere Analyse- und Statistikmöglichkeiten gegeben.
Syntax
objects.query('<query>')
Diese Funktion fordert ein Lookup der gefundenen Objekte an. Der Aufruf ist fast äquivalent zur Verwendung von search, mit dem Unterschied, dass Sie mit query.find()
auch Unterobjekte finden können.
Syntax
let results = objects.query('name:demo').find();
Ergebnis
Sie erhalten ein Array mit Objekten zurück und können direkt mit den Objekten arbeiten. Die Funktion arbeitet im Gegensatz zu search langsamer, es dauert also länger, bis sie die Objekte zurückerhalten.
[ 123456, 123457, 123458 ]
Erwarten Sie eine größere Menge an Treffern, sollten Sie die Anzahl der zurückgegebenen Ergebnisse mit limit()
beschränken.
Syntax
let results = objects.query('*').limit(10).find();
Ergebnis
Sie erhalten die ersten zehn Treffer zurück.
Hinweis: Die Suche mit search/find
ist auf maximal 10.000 Elemente (limit) beschränkt. Wenn Sie mit einer Suchanfrage mehr Elemente in einem Durchlauf durchsuchen möchten, nutzen Sie cursor
und / oder iterate
.
Diese Funktion ruft die nächsten zehn Treffer ab.
Syntax
let results = objects.query('*').start(10).limit(10).find();
Ergebnis
Sie erhalten die Treffer 11–20 zurück.
Sie können die Ergebnismenge sortieren. Wenn Sie keine explizite Sortierung durch sort
angegeben haben, sortiert das System automatisch absteigend nach dem letzten Änderungsdatum der Objekte.
Syntax
let results = objects.query('*').sort('createdate').limit(10).find();
Ergebnis
Sie erhalten die zehn ältesten Objekte (nach Erstelldatum aufsteigend) zurück.
Sie können mehrere Sortieranfragen kombinieren.
Syntax
let results = objects.query('*').sort('nameextension', 'contentsize desc').limit(10).find();
Ergebnis
Sie erhalten die Objekte primär nach der Namenserweiterung aufsteigend und sekundär nach der Dateigröße absteigend zurück.
Verwenden Sie Teil-Suchanfragen häufiger, ist es möglich, diese in getrennte Filter auszulagern. Dadurch signalisieren Sie der Suchmaschine, dass diese gefilterte Mengen bevorzugt im Cache halten kann.
Syntax
let results = objects
.query('name:test')
.filter('inpath:9999', 'nameextension:pdf')
.sort('contentsize desc')
.limit(5)
.find();
Ergebnis
Sie erhalten die fünf größten, noch nicht gelöschten (inpath:9999) PDF-Dokumente zurück, bei denen das Wort "test" im Namen vorkommt. Die Suche nach name:test
bildet hier die Ausnahme. Benutzen Sie stattdessen inpath:9999
und nameextension:pdf
.
Diese Funktion fragt ohne Datenbankabfrage direkt aus dem Index Attribute ab und zeigt an, wie viele Treffer die Suche insgesamt hatte.
Syntax
let result = objects.query('isfolder:true').limit(10).search('id', 'name'); 'Total: ' + result.total + '\n\n' + result.rows.map(function(row) { return row.id + ': ' + row.name; }) .join('\n');
Ergebnis
Sei erhalten eine Übersicht über die Gesamtanzahl an Ordnern inklusive IDs und Namen der zehn zuletzt geänderten Ordner zurück.
{ "nextCursor": null, "total": 3, "highlights": null, "rows": [ { "name": "demo", "id": "6909861" }, { "name": "demo-Info Profile", "id": "6909862" }, { "name": "Demo", "id": "6909863" } ], "facetFields": null, "facets": null }
Ist lediglich die Anzahl der Treffer interessant, kann die Ergebnismenge selbst sogar völlig unterdrückt werden:
let fileCount = objects.query('isfolder:false').limit(0).search().total;
Für große Datenmengen sollten Sie nicht mehr start()
für Paging verwenden, sondern cursor()
. Hierbei liefert das System bei jedem Suchergebnis ein Cursor für die nächste Anfrage mit. Das hat außerdem den Vorteil, dass auch bei zwischenzeitlichen Veränderungen in der Ergebnismenge, insbesondere bei neuen / entfernten Elementen vor der aktuellen Position, ein konsistentes Paging erreicht wird:
let result = objects.query('isfolder:true').cursor().limit(500).search('id'); // .. do something with result.rows .. result = objects.query('isfolder:true').cursor(result.nextCursor).limit(500).search('id'); // .. do something with result.rows .. // ...
Diese Funktion geht alle gefundenen Objekte im System durch und führt für jedes Objekt eine gewünschte Aktion durch.
cursor
und eine Begrenzung pro Suche.
Syntax
// iterate over specific fields without retrieving the associated objects objects.query('isfolder:true').iterate('uuid', 'name', function(row) { // .. do something with row.uuid and row.name .. });
Sie können der Funktion "query.iterate" ein limit mitgeben. Dadurch iteriert das System nicht über alle, sondern nur über x Objekte.
Syntax
// objects.query('isfolder:true').limit(10).iterate('uuid', 'name', function(row) { // .. do something with row.uuid and row.name .. });
Ergebnis
Sie erhalten 10 Ordner inklusive der UUID und des Ordnernamens zurück.
Diese Funktion durchläuft wie query.iterate alle Objekte, liefert aber ein anderes Ergebnis pro Objekt.
Syntax
// visit all matching objects objects.query('ancestors:mailobject').forEach(function(object) { // .. do something with the object .. });
Ergebnis
Sie erhalten alle E-Mail-Objekte zurück.
Sie können auch nach verborgenen Objekten suchen, die sonst üblicherweise ausgeblendet werden (History-Objekte, Unterobjekte).
Syntax
objects.query('*').includeHidden(true).limit(0).search().total;
Ergebnis
Sie erhalten die gesamte Anzahl an indizierten Objekten im System zurück.
Um die Ergebnismenge weiter zu analysieren, werden zwei Verfahren unterstützt:
Bei Letzterem bezieht sich die Analyse in jedem Fall auf die im Suchergebnis enthaltenen Objekte. Möchten Sie alle Objekte analysieren, suchen Sie nach *
.
Feldbasiertes Faceting ermöglicht auf einfache Weise, Wertemengen für bestimmte Felder zu erzeugen.
objects .query('area:Kundenakte ac_customernumber:12345') .facetFields('nameextension', 'ac_ticketstate') .facetLimit(3) .facetSort('count') .limit(0) .search() .facetFields;
Hier wird innerhalb einer bestimmten Kundenakte nach vorhandenen Dateitypen und verwendeten Ticketstatus gesucht (die eigentlichen Suchtreffer sind nicht relevant, daher auf 0 limitiert). Das Ergebnis hat folgende Form:
{ nameextension: { pdf: 12345, eml: 5432, html: 123 }, ac_ticketstate: { closed: 123, waiting: 12, open: 1 } }
Die Wertemengen wurden nach Vorkommen (count) sortiert und auf drei Werte beschränkt.
Wenn die Suchergebnisse selbst nicht unterdrückt werden, lässt sich damit etwa einfach eine Verfeinerung von Suchergebnissen ermöglichen, indem Sie einen oder mehrere der zurückgegebenen Werte vom Benutzer als Filter auswählen und auf dieser Basis eine neue Suche starten.
Vorhandene Methoden und ihre Parameter
Methode | Parameter | Beschreibung |
---|---|---|
facetFields | <field>, ... | Felder, die berücksichtigt werden sollen. default keine |
facetMinCount | <count> | Mindestanzahl an Stellen, an denen ein Wert vorkommen muss, um berücksichtigt zu werden. Achtung: Unbeabsichtigte Einsicht durch Angabe 0.Es werden Feldwerte ausgegeben, die laut ACL für den aktuellen Benutzer nicht sichtbar wären. Tragen Sie einen positiven Wert ein. default 1 |
facetLimit | <limit> | Maximale Anzahl an Werten pro Feld, die zurückgegeben werden sollen. default 100 |
facetMissing | true/false | Zusätzlicher Pseudo-Wert (leerer String), der die Stellen zählt, an denen das Feld keinen Wert hatte. default false |
facetSort | <order> | Sortierung der Werte, entweder count oder index. • default count: Vorkommen index: Alphabetisch |
Hinweis: Diese Beschreibung ist gekürzt und umfasst nicht alles.
Über erweitertes Faceting wird sowohl die Funktionalität des einfachen Faceting (Wertemengen) abgedeckt als auch zusätzliche Analyse- und Aggregierungsfunktionalität:
objects .query('*') .limit(0) .facets({ mails: { type: 'query', q: 'ancestors:mailobject' }, mail_content: { type: 'query', q: 'ancestors:(mailobject OR maildocumentobject)', facet: { sum_size: 'sum(contentsize)' } }, extensions: { type: 'terms', field: 'nameextension', minCount: 10 }, content: { type: 'terms', field: 'classname', facet: { sum_size: 'sum(contentsize)' }, sort: { sum_size: 'desc' }, limit: 99999 } }) .search() .facets;
Dieses Beispiel ermittelt folgende Informationen über alle für den aktuellen Benutzer sichtbaren Objekte (*
):
ancestors:mailobject
passen (Anzahl Mails)ancestors:(mailobject OR maildocumentobject)
passen (Anzahl Mails und Mail-Teile)
classname
(Alle vorkommenden Objektklassen)
Sie können die Suchmaschine ebenfalls dazu verwenden, um im Dokumentinhalt oder in Metadaten hervorzuheben, an welcher Stelle der Suchtreffer aufgetreten ist.
objects .query('test') .highlights({ limit: 5 }) .limit(10) .search('uuid', 'name');
Das Suchergebnis enthält nun neben UUID und Name der passenden Objekte auch die Treffer innerhalb des Inhalts der jeweiligen Objekte im Abschnitt "highlights", unterhalb der UUID des jeweiligen Objekts.
Parameter
Parameter | Beschreibung | Default |
---|---|---|
field | Wählt das Index-Feld aus, in dem nach Treffern gesucht werden soll. Hier kann auch ein Array von Feldnamen übergeben werden, um über mehrere Felder hinweg das Highlighting zu erzeugen. Beispiel: [ 'contentonly', 'description' ] |
'contentonly' |
limit | Legt fest, wie viele Treffer pro Objekt maximal zurückgegeben werden sollen. | 100 |
pre | Definiert die Zeichenfolge, die vor jedem Treffer eingefügt wird. | '[' |
post | Definiert die Zeichenfolge, die nach jedem Treffer eingefügt wird | ']' |
query | Gibt eine von der Suche unabhängige query für das Highlighting mit. | keine |
allFields | true Nimmt das Highlighting in allen Feldern vor. false Nimmt das Highlighting nur in den Feldern vor, in denen das jeweilige Wort gefunden wurde. |
false |
context | Definiert, wie viele Zeichen um einen Treffer herum zurückgeliefert werden sollen. (Ungefähre Angabe, auch die Worte an sich werden als Ganzes in Betracht gezogen.) | 100 |
Mit diesen Funktionen erzeugen Sie neue Objekte einer definierten Klasse mit initialen Attributen. Die Funktion "tryCreate()" prüft zudem, ob das zu erzeugende Objekt bereits vorhanden ist und liefert es in diesem Fall zurück. Die Attribute eines bereits existierenden Objekts werden dabei nicht verändert.
objects.create('<class>', data) objects.tryCreate('<class>', data)
Es folgt ein Überblick über die unterstützten Werte für class
und data
.
Alle Klassen
Für alle Klassen wird das Attribut target
unterstützt, das im Fall von Notizen das zugehörige Hauptobjekt und im Fall der anderen Klassen den Zielordner bestimmt. Für alle Klassen außer Notizen existiert zusätzlich ein optionales Attribut path
, das einen Pfad unterhalb von target definiert, in den das Objekt abgelegt werden soll. Dieser Pfad wird bei Bedarf angelegt.
Hinweis: Sie können Ordner durch den Befehl nicht erstellen, siehe Abschnitt find mit create.
Tipp: Für Benutzer, Gruppen und ACLs verwenden Sie üblicherweise kein target
, sondern nur einen relativer path
unter dem jeweiligen Wurzelordner für die Objektklasse.
Mit file
erzeugen Sie eine Datei. Die Angabe von target
oder path
ist notwendig. Der Offset-Wert von path, wenn dieser ohne '/' beginnt, ist /agorum/roi/Files
:
let file = objects.create('file', { name: 'test.txt', description: 'Eine Textdatei', target: target, path: 'Ordner 1/Ordner 2' });
Dieser Aufruf legt eine leere Textdatei im Ordner /agorum/roi/Files/Ordner 1/Ordner 2
an. Wenn dieser Dateiname im Zielordner schon belegt ist, hängt das System automatisch ein numerisches Suffix an.
Weitere Parameter:
Parameter | Beschreibung | Beispiel |
---|---|---|
target | <Object> | • target let target = objects.find('/agorum/roi/Files');• target darf kein String sein. |
content | <stream> | • content: object.contentStream • Hier wird aus einer vorhandenen Datei der Content gestreamt. |
path | Relative Angabe: • Wird an target angehängt. • Falls die Ordnerstruktur nicht existiert, wird diese erstellt. Absolute Angabe: • Wird nicht an target angehängt. • target wird ignoriert, es wird nur path benutzt.• Falls die Ordnerstruktur nicht existiert, wird diese erstellt. |
Relative Angabe: • <target>/<path>: 'Ordner 1/Ordner 2' Absolute Angabe: • <path>: '/agorum/roi/Files/Demo/x/y' |
Hinweise:
In path
können Sie keine Platzhalter wie z. B. ${date:yy/MM/dd} nutzen.
path
kann nicht mit einem agorum Object umgehen. Es wird zudem ein String erwartet.
Sie können Content auch setzen, wenn das Objekt angelegt ist. Hier können Sie auch einen String setzen:
file.contentString = 'hhhh';
Das ist ein Sonderfall, der hier dokumentiert wird, aber momentan noch keine Methode von "objects" ist.
Um einen "Ordner" anzulegen, benötigen Sie ein Ordner-Objekt. Auf diesem Ordner-Objekt können Sie jetzt direkt die Methode "createPath(path)" aufrufen.
Beispiel
Sie wollen direkt unter "/agorum/roi/Files" einen neuen Ordner oder eine Ordnerstruktur anlegen. Dann können Sie das so umsetzen:
let files = objects.find('/agorum/roi/Files'); // Jetzt wollen Sie darunter einen Ordner "Beispiele" anlegen let beispiele = files.createPath('Beispiele'); // Es wird der Ordner "Beispiele" zurückgegeben // Jetzt wollen Sie noch einen Pfad anlegen let pdf = files.createPath('Archive01/Dokumente/Ablage/PDF'); // Es wird der letzte Ordner zurückgegeben
Hinweis: Wenn der Pfad bereits existiert, wird der vorhandene Pfad zurückgegeben.
Beispiel
Wenn es den Pfad "agorum/roi/Files/Archive01/Dokumente/Ablage/PDF" schon gibt, wird der Ordner "PDF" zurückgegeben.
Beispiel templates.fill mit createPath zum Erstellen einer Ordnerstruktur nach einem Datum
Hier noch ein Beispiel in Kombination mit templates.fill
und einem Datum.
Mit pai
erzeugen Sie einen ParameterAccessIdentifier (PAI). Diesen können Sie zur Steuerung von Oberflächenfunktionen nutzen.
let pai = objects.tryCreate('pai', { name: 'Test_1', acl: 'Published' });
Dieser Aufruf legt einen neuen PAI mit dem Namen Test_1 an. Ist dieser bereits vorhanden, so wird dieser lediglich zurückgegeben (wegen dem Aufruf mit tryCreate).
Weitere Parameter:
Parameter | Beschreibung |
---|---|
name | Name des PAI Legt standardmäßig immer ein ACL mit dem Namen "ACL_PAI_[Name-des-PAI]_" an, etwa "ACL_PAI_Test_1_". |
acl (optional) | Übergibt ein existierendes ACL. Gruppen / Benutzer des ACLs werden mit denselben Rechten in das PAI übertragen. Geben Sie kein ACL an, erhält das zu erstellende PAI keinen Eintrag. |
Hinweis: Möchten Sie, dass die Sichtbarkeit der Module auf der Startseite auch für den Administrator gilt, müssen Sie hierzu den PAI im desk4web bearbeiten und den Parameter "ACL gilt auch für Administratoren" setzen.
Mit user
legen Sie einen Benutzer an, optional mit Bild:
// Legt Benutzer an let user = objects.create('user', { name: 'testuser', password: 'testpass', path: 'Testbenutzer', admin: false, givenName: 'Test', familyName: 'User', language: 'de', emailAddresses: [ 'testuser@agorum.com' ], adminEnabled: false, readOnlyMode: false }); //Legt ein Bild zum Benutzer an (optional) let image = user.getProfilePicture(); // Wenn noch kein Bild vorhanden, dann anlegen if (!image) { let home = user.primaryUserProfile.homeFolder; image = objects.create('file', { name: 'picture.png', target: home }); user.setProfilePicture(image, true); image = user.getProfilePicture(); // Das Bild in den Benutzer laden objects.find('/agorum/roi/Files/irgeneinbild.png').streamContent(image); }
Eigenschaften des Benutzers mitgeben
Mit folgenden Parametern geben Sie Eigenschaften des Benutzers mit.
Parameter | Beschreibung |
---|---|
adminEnabled | true Der Benutzer ist ein Administrator. false Der Benutzer ist kein Administrator. Mit der Methode adminEnabled fragen Sie diesen Parameter ab. |
readOnlyMode | true Der Benutzer hat nur Leserechte (Lese-Benutzer). false Der Benutzer hat diejenigen Rechte, die er über andere ACLs erhält. Mit der Methode readOnlyMode fragen Sie diesen Parameter ab. |
Beispiel
objects.find('user:<Name des Benutzers, etwa demo>').readOnlyMode;
Mit group
legen Sie eine Gruppe an:
let group = objects.create('group', { name: 'GRP_Buchhaltung', path: 'Testfirma', members: [ 'user:user1', user ] });
Die neu angelegte Gruppe enthält zwei Benutzer:
Wenn Sie einen path angeben:
path: 'academy.workflow/Beispiele/Neuer Ordner'
Weitere Member zur Gruppe hinzufügen
Mit folgendem Code fügen Sie nachträglich weitere Members zur Gruppe hinzu:
let members = [ 'group:Gruppenname1', 'user:Username1' ]; // es werden lediglich Gruppen oder User hinzugefügt, die auch vorhanden sind function addMembersToGroup(group, members) { group.addMembers(members.map(member => objects.tryFind(member)).filter(m => m)); }
Member aus einer Gruppe erweitern
Wenn Sie die Members einer Gruppe erweitern möchten, müssen Sie sicherstellen, dass das System weiß, dass es sich um eine Gruppe handelt:
let singlegroup = "GRP_Musterfirma Group GmbH"; let members = [ 'group:GRP_INFOS UND WISSEN', 'group:GRP_KUNDEN', 'group:GRP_MARKETING', 'group:GRP_PERSONAL', ]; addMembersToGroup(objects.tryFind('group:' + singlegroup), members); // es werden lediglich Gruppen oder User hinzugefügt, die auch vorhanden sind function addMembersToGroup(group, members) { group.addMembers(members.map(member => objects.tryFind(member)).filter(m => m)); }
Member aus einer Gruppe entfernen
Mit folgenden Code entfernen Sie die Members aus einer Gruppe:
let members = [ 'group:Gruppenname1', 'user:Username1' ]; // es werden lediglich Gruppen oder User entfernt, die auch vorhanden sind group.removeMembers(members.map(member => objects.tryFind(member)).filter(m => m));
Member aus einer Gruppe auslesen
Mit folgenden Befehlen lesen Sie die Mitglieder aus einer Benutzergruppe aus:
Befehl | Beschreibung |
---|---|
directUserMembers | Liest alle Benutzer aus einer Gruppe aus, die direkt in dieser enthalten sind. |
allUserMembers | Liest alle Benutzer aus einer Gruppe und deren enthaltenen Untergruppen aus. |
directMembers | Gibt alle Benutzer und Benutzergruppen einer Gruppe zurück, die direkt in dieser enthalten sind. |
allMembers | Gibt alle Benutzer und Benutzergruppen einer Gruppe und deren enthaltenen Untergruppen zurück. |
Beispiel
objects.find('group:<Name der Gruppe, z.B. GRP_wf_allgemein_beobachter>').directUserMembers.map(user => user.UUID);
Mit acl
legen Sie ein ACL an:
let acl = objects.create('acl', { name: 'ACL_Kundenakten', path: 'Testfirma', entries: [ { entity: 'group:GRP_Verwaltung', access: 'write' }, { entity: group, access: 'read' }, { entity: 'user:user1', access: 'read' revoke: true } ] });
Das ACL gewährt der Gruppe "GRP_Verwaltung" Schreibrechte, der Gruppe aus dem vorherigen Beispiel Leserechte, mit Ausnahme des Benutzers "user1". Für access
sind folgende Werte möglich. Die Werte in Klammer mit xml: ist die Kennung für das XML-Script über agoscript:
Wert | Zugriff |
---|---|
xml:AG_PB_READ | r = read = Leserechte |
xml:AG_PB_CHECK_OUT | c = check_out = Leserechte + Check-out/Check-in-Rechte |
xml:AG_PB_WRITE | w = write = Leserechte + Schreibrechte |
xml:AG_PB_PROTECTED | p = protected = Leserechte + das Recht, ein neues Objekt anzulegen |
xml:AG_PB_ALL | a = all = Vollrechte |
Momentan können Sie ACLs, die auch für Admins gelten, nicht direkt auf diese Weise anlegen. Sie können das Flag aber nachträglich setzen:
acl.adminsAffected = true;
Mit note erzeugen Sie eine neue Notiz. Hierbei unterscheidet das System zwischen dem Text-Format und dem HTML-Format
Text-Format
objects.create('note', { content: 'Hallo Welt', target: file, recipients: [ 'group:GRP_Mitarbeiter' ] });
HTML-Format
objects.create('note', { content: '<p>Hallo Welt<br>Neue Zeile</p>', target: file, noteFormat: 'text/html', recipients: [ 'group:GRP_Mitarbeiter' ] });
Die Notiz wird an die oben erzeugte Datei gehängt und an alle Mitglieder der Gruppe "GRP_Mitarbeiter" adressiert.
Möchten Sie, dass als Absender der Notiz nicht der Systemadministrator "roi" genannt wird, können Sie auch den Absender setzen.
Text-Format
/* global sc */ //Gibt den Absender an let objectsUser = objects(sc.asUser(objects.find('user:demo'))); objectsUser.create('note', { content: 'Hallo Welt', target: file, recipients: [ 'group:GRP_Mitarbeiter' ] });
HTML-Format
/* global sc */ //Gibt den Absender an let objectsUser = objects(sc.asUser(objects.find('user:demo'))); objectsUser.create('note', { content: '<p>Hallo Welt<br>Neue Zeile</p>', target: 'text/html', recipients: [ 'group:GRP_Mitarbeiter' ] });
Mit dieser Funktion aktualisieren Sie spezielle Klassen, etwa User. Es folgt ein Überblick über die unterstützten Werte für class
und data
.
objects.update('<class>', object, data)
user
Mit user
aktualisieren Sie einen Benutzer:
let user = objects.update('user', objects.find('user:USERNAME'), { name: 'testuser', password: 'testpass', admin: false, givenName: 'Test', familyName: 'User', language: 'de', emailAddresses: [ 'testuser@agorum.com' ] });
Die jeweiligen Felder sind optional. Geben Sie beispielsweise nur password
an, aktualisiert sich auch nur das Passwort.
Mit dieser Funktion fügen Sie Objekte zu bestehenden Objekten hinzu, die weitere Objekte beinhalten können (Beispiel: ein weiterer Grantee zu einer bestehenden ACL).
objects.addTo('<class>', object, data)
Folgend eine Übersicht der bisher unterstützten Werte für class
und den daraus resultierendem data.
acl
objects.addTo('acl', objects.find('group:World'), { aclObject: objects.find('acl:Testacl'), access: 'read', revoke: false });
Es wird die Gruppe World
dem bestehenden ACL Testcl
mit lesendem Recht (read
) zugewiesen.
Weitere Werte für access
:
Wert | Zugriff |
---|---|
read | Lesender Zugriff |
write | Schreibender Zugriff |
all | Vollzugriff |
check_out | Dokument auschecken |
protected | Dokument schreibgeschützt setzen |
Weitere mögliche Werte für revoke
:
Wert | Beschreibung |
---|---|
true | Entzieht dem Benutzer das angegebene Recht. |
false | Gibt dem Benutzer das angegebene Recht. |
Mit dieser Funktion entfernen Sie Objekte aus bestehenden Objekten, die weitere Objekte beinhalten können (Beispiel: das Löschen eines Grantees aus einer bestehenden ACL). Folgend eine Übersicht der bisher unterstützten Werte für class
und den daraus resultierendem data.
objects.removeFrom('<class>', object, data);
acl
objects.removeFrom('acl', objects.find('acl:Testacl'), objects.find('group:World'));
Es wird die Gruppe World
aus der bestehenden ACL Testacl
entfernt.
In dieser Ausprägung von removeFrom
ist object
die bestehende ACL und data der Grantee
, der aus der ACL entfernt werden soll.
Diese Funktion liefert true zurück, wenn der angemeldete Benutzer durch die angegebene ACL zumindest lesendes Recht (read) erhält.
objects.mayDiscover('name-der-acl');
Diese Funktion liefert true zurück, wenn der angemeldete Benutzer durch die angegebene ACL zumindest die Berechtigung erhält, den Inhalt zu ändern (write).
objects.maySetContent('name-der-acl');
Mit diesen Funktionen erzeugen oder entfernen Sie Verlinkungen des übergebenen Objekts in einem oder mehreren angegebenen Ordnern. Der Unterschied zwischen link()
/unlink()
und add()
/remove()
bezieht sich auf Scope-ACLs.
objects.link(object, targets, name) objects.unlink(object, parents) objects.add(object, targets, name) objects.remove(object, parents)
In agorm core müssen grundsätzlich Objekte mit einem Haupt-ACL versehen werden. Mit diesem ACL ist es möglich, alle Anforderungen an die Berechtigungen umzusetzen.
Um die Umsetzung komplexer Anforderungen wesentlich zu vereinfachen, wurde die Technik der Scope-ACL's (zu Deutsch: Geltungsbereich/Anwendungsbereich) eingeführt. Scope-ACL's sind ACL's, die sich auf einen bestimmten Bereich (Scope) beziehen. Diese Technik bedeutet, dass Sie beliebig viele ACL's als Scope-ACL's auf ein Objekt setzen können.add()
verwaltet somit zusätzlich noch die Scope-ACLs auf dem Objekt:
add()
ergänzt fehlende Scope-ACLs. Liegt zudem ein Objekt unter demselben Namen im Zielordner, bricht add ab, da diese Funktion den Dateinamen nicht hochzählt im Gegensatz zu link().
remove()
entfernt nicht mehr benötigte Scope-ACLs.Für targets
oder parents
können einzelne Objekte oder Arrays von Objekten übergeben werden, parents
ist außerdem optional – bei Fehlen werden alle aktuellen Elternordner verwendet. Wird name
gesetzt, kann das Objekt außerdem noch umbenannt werden – bei Namenskollisionen wird hier automatisch ein numerisches Suffix angehängt.
Tipps:
Nutzen Sie das Funktionspaar (link()
/unlink()
, add()
/remove())
zusammen, um Objekte zu verschieben.
Nutzen Sie eine der Funktionen link()/
add(),
um Dokumente zu verlinken.
Nutzen Sie unlink()
/remove(),
um Verlinkungen zu entfernen.
Mit dieser Funktion erstellen Sie eine Kopie des übergebenen Objekts in einem oder mehreren angegebenen Ordnern. Das ACL des ersten Ordners wird als ACL der Kopie verwendet, eventuelle weitere ACLs als Scope-ACL. Optional können Sie das Objekt umbenennen. Namenskollisionen werden vermieden.
Die Funktion gibt als Ergebnis die Kopie des Objekts zurück.
let newObject = objects.copy(object, targets, name)
Mit dieser Funktion entfernen Sie Verlinkungen des übergebenen Objekts in einem oder mehreren übergebenen Ordnern und markieren sie dort als gelöscht. Lassen Sie parents
weg oder geben explizit alle Elternordner an, legt das System das Objekt außerdem in den Papierkorb.
objects.trash(object, parents)
Mit rename
benennen Sie ein Objekt um. Bei Namenskollisionen hängt das System automatisch ein numerisches Suffix an, ähnlich wie bei add
, link
und copy.
objects.rename(object, name)
objects.convert(object, { name: 'test.txt', // optional, wenn nicht angegeben, wird der übergebene Name genommen. description: 'Eine Textdatei', // optional, wenn nicht angegeben, wird die übergebene Beschreibung genommen. path: 'Ordner 1/Ordner 2', // entweder muss "path" oder "target" angegeben sein. format: 'pdf', // Pflicht, gibt das Zielformat an. target: folder // entweder muss "path" oder "target" angegeben sein. }); //Es gelten die gleichen Regeln wie oben bei "convert" objects.tryConvert(object, { name: 'test.txt', description: 'Eine Textdatei', path: 'Ordner 1/Ordner 2', format: 'pdf', // Pflicht target: folder // Pflicht });
Die Parameter format
und target
(oder path
) sind Pflicht, als Name wird im Standard <baseName>.<format>
verwendet, ansonsten wird der Rest 1:1 an objects.create('file')
durchgereicht.
Der Unterschied zwischen convert()
und tryConvert()
besteht darin, dass Erstere einen Fehler wirft, wenn das Objekt nicht gefunden wird, während Letztere null
zurückgibt.
Hinweis: Grundlegende Informationen zur Dokumentkonvertierung erhalten Sie in der Dokumentation DocumentService.
Beispiel (inklusive. Prüfung, ob eine Konvertierung überhaupt funktioniert):
let beans = require('common/beans');..
let pdf = null;
if (beans.selected(object, '[convertible(pdf)]')) {
pdf = objects.tryConvert(object, {
format: 'pdf',
path: '/agorum/roi/Files/Samples'
});
}
Das übergebene "object" wird in ein PDF konvertiert. Wenn die Konvertierung nicht funktioniert, wird null
zurückgegeben.
Hinweis: Sie können für format
alle Dokumentformate angeben, für die ein Konverter vom vorhandenen Quellformat aus existiert. Die möglichen Konverter finden Sie in der MetaDb unter folgendem Pfad und dort in den jeweiligen Unterordnern:
MAIN_MODULE_MANAGEMENT/documentservice/control/services
Mit writer
schreiben Sie Text in eine Datei, wodurch diese Datei zu einer Logdatei wird. Bei dieser Datei kann es sich etwa um eine TXT- oder um eine HTML-Datei handeln, also alle Dateien, in die Text geschrieben werden kann.
Beispiel
let object = objects.find('1591610'); // ID '1591610' dient als Beispiel und verweist auf die genutzte LOG-Datei objects.writer(object, w => { w.println('Bla'); w.print('Irgendwas', '+ etwas weiteres'); // Ausgabe: Irgendwas + etwas weiteres w.print('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt w.println('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt // best practice w.print([ 1, 2, 3 ].join(' ')); [ 1, 2, 3 ].forEach(w.print); [ 1, 2, 3 ].forEach(w.println); });
Ausgabe
Bla Irgendwas + etwas weiteresWert von x: x Test 123Wert von x: x Test 123 1 2 31 0 1,2,32 1 1,2,33 2 1,2,31 0 1,2,3 2 1 1,2,3 3 2 1,2,3
Führen Sie das obige Skript erneut aus, aber mit anderem Textinhalt, wird der neue Inhalt der Datei angefügt.
Wenn Sie mehrere Texte über println
ausgeben, wird der zweite Eintrag an den ersten usw. angehängt, er taucht also dann unterhalb des ersten Eintrags in der Logdatei auf:
let object = objects.find('1591610'); // ID '1591610' dient als Beispiel und verweist auf die genutzte LOG-Datei objects.writer(object, w => { //erstes 'Bla' w.println('Bla'); w.print('Irgendwas', '+ etwas weiteres'); // Ausgabe: Irgendwas + etwas weiteres w.print('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt w.println('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt // best practice w.print([ 1, 2, 3 ].join(' ')); [ 1, 2, 3 ].forEach(w.print); [ 1, 2, 3 ].forEach(w.println); //Zweites 'Bla' w.println('Bla'); w.print('Irgendwas', '+ etwas weiteres'); // Ausgabe: Irgendwas + etwas weiteres w.print('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt w.println('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt // best practice w.print([ 1, 2, 3 ].join(' ')); [ 1, 2, 3 ].forEach(w.print); [ 1, 2, 3 ].forEach(w.println); });
Ausgabe
Bla Erste Logausgabe Irgendwas + etwas weiteresWert von x: x Test 123Wert von x: x Test 123 1 2 31 0 1,2,32 1 1,2,33 2 1,2,31 0 1,2,3 2 1 1,2,3 3 2 1,2,3 Bla Zweite Logausgabe Irgendwas + etwas weiteresWert von x: x Test 123Wert von x: x Test 123 1 2 31 0 1,2,32 1 1,2,33 2 1,2,31 0 1,2,3 2 1 1,2,3 3 2 1,2,3
Parameter | Beschreibung |
---|---|
object | Hängt den Text an das angegebene Objekt an. Das Objekt muss zuvor über objects.find gefunden werden. Als Objekt empfiehlt sich eine TXT- oder eine HTML-Datei. |
encoding (optional) | Gibt ein spezielles Encoding (im Format: 'ISO-8859-15') mit. Im Standard wird UTF-8 verwendet, egal, wie das System eingestellt ist. |
callback | Über diese Funktion kann direkt geschrieben werden. Zur Verfügung stehen diese Methoden: print() Gibt die übergebenen Parameter direkt aus. Mehrere Parameter werden durch Leerzeichen getrennt. println() G ibt alle Parameter aus und erzeugt danach einen Absatz. Mehrere Parameter werden durch Leerzeichen getrennt.flush() Ermöglicht das Speichern der Datei, um den Inhalt sichtbar zu machen. Dies kann etwa nach allen paar Einträgen stattfinden. |
makeHistory | true Erzeugt beim Schreiben auf eine vorhandene Datei eine Historie. false (Standard) Erzeugt beim Schreiben auf eine vorhandene Datei keine Historie. |
Beispiel eines mitgegebenen encodings
objects.writer(object, 'ISO-8859-15', w => { w.println('abc;defä'); });
Beispiel einer Historie
objects.writer(object, 'ISO-8859-15', w => { w.println('abc;defä'); }, true);
Beispiele zum Ausgeben von Arrays
let values = [ 1, 2, 3 ]; objects.writer(object, 'ISO-8859-15', w => { // Einträge per Semikolon trennen w.print(values.join(';')); // Pro Eintrag eine neue Zeile schreiben: values.forEach(w.println); });
Über die Angabe eines sessionControllers
zu require('common/objects') steuern Sie, ob eine Historie für das Objekt erzeugt werden soll oder nicht, wenn in die Datei geschrieben wird:
// Es wird keine Historie für das geladene Objekt über objects erstellt. let objects = require('common/objects')(sc.asService()); // Es wird eine Historie für das geladene Objekt über objects erstellt. let objects = require('common/objects');
Komplettes Beispiel
/* global sc */ let objects = require('common/objects'); let object = objects.find('1591610'); ID '1591610' dient als Beispiel objects.writer(object, w => { w.println('Bla'); w.print('Irgendwas', '+ etwas weiteres2'); // Ausgabe: Irgendwas + etwas weiteres w.print('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt w.println('Wert von x:', 'x', 'Test 123'); // intern mit Leerzeichen getrennt // best practice w.print([ 1, 2, 3 ].join(' ')); [ 1, 2, 3 ].forEach(w.print); [ 1, 2, 3 ].forEach(w.println); sc.asService(); });
Mit dieser Funktion lesen Sie den Content eines Objekts in UTF-8.
let contentString = objects.getContentString(object);
Parameter | Beschreibung |
---|---|
object | Liest vom Objekt den Content in UTF-8. |
Return | Beschreibung |
---|---|
contentString | Enthält den Content des Objekts 'object'. |
Mit dieser Funktion schreiben Sie den Content eines Objekts in UTF-8.
objects.setContentString(object, contentString);
Parameter | Beschreibung |
---|---|
object | Schreibt den Content in UTF-8 in das Objekt. |
contentString | Definiert den Content, der in UTF-8 in das Objekt 'object' geschrieben wird. |
Siehe Systemflags per JavaScript setzen.
Mit dieser Funktion indizieren Sie ein Objekt neu.
Syntax
objects.reIndex(object);
Mit dieser Funktion erzwingen Sie die Neuerstellung des Dokumententextes des übergebenen Objekts per OCR, sofern ein entsprechender Konverter verfügbar ist.
Syntax
objects.forceOcr(object);
Hinweis: Erstellen Sie ein neues Objekt oder extrahieren etwa einen Anhang aus einer E-Mail innerhalb eines Workflows, dann können Sie forceOcr
nicht sofort verwenden. Ein Workflow läuft normalerweise innerhalb einer Transaktion ab, wodurch die neuen Objekte nicht sofort zur Verfügung stehen. Bauen Sie den Knoten undefined>delay ein, um dem Problem entgegenzuwirken und die aktuelle Transaktion abzuschließen.
Parameter
Parameter | Beschreibung |
---|---|
object | Definiert das Objekt, von dem das System den Text neu erzeugt. |
parameters |
(optional) Definiert weitere OCR-Parameter, die Sie mitgeben können (siehe agorum core active folder - Zusätzliche Parameter). |
Beispiel
objects.forceOcr(object, [ '--bitonal-auto:True', '--bitonal-brightness:100', '--bitonal-contrast:1', '--barcode-types:all', '--worker-threads:1', '--work-depth:1', ]);