[gelöst] FieldAccess ohne Modul kontrollieren

am 24.03.2015 - 08:43 Uhr in
Hallo,
ich habe den Großteil meiner Anforderungen an ein CMS mit Modulen in Drupal abgebildet und weil das nicht immer ganz reicht, habe ich alle Sonderthemen so gelöst, dass ich eine PHP-Datei als Block eingebunden habe, die dann den Rest erledigt.
Nun bin ich an einem Punkt, wo ich nicht sicher bin, wie es geht und ob es in meine "Sonder"-PHP noch reinpasst.
Was will ich tun? Ein Node besteht aus vielen Feldern. Für ein Freemium-Modell soll je nach Node einstellbar sein, ob es grundsätzlich dazugehört oder nicht. Damit scheiden die globalen FieldAccess-Module aus, die ich bisher getestet hatte. Dann kann man eine Bezahlung durchführen (Drupal externes System) und erhält dann den gesamten Inhalt.
Was brauche ich? Nun mit will das beschränken auf einige Felder nicht gelingen. Es gibt dafür ja diesen hook_field_access, aber ich verstehe nicht so recht, wie ich den anwende, bzw. glaube ich, dass dies nur innerhalb von Modulen funktioniert. Ist dem so? Oder bekomme ich das auch in meiner "Sonder"PHP hin? Die "Sonder"PHP würde ja auch die Verbindung zum Bezahlsystem herstellen müssen, also wenn bezahlt, dann anzeigen sonst nicht.
Ich habe mir schon ein paar Module angesehen und in den Code geschaut. Dort wird der hook ja beschrieben und programmiert, aber wirklich verstanden habe ich nicht, wie er aufgerufen wird und warum er zum Tragen kommt.
Die mal das Beispiel aus dem Field_Permission - Modul
<?php
/**
* Implementation of hook_field_access('view').
*/
function _field_permissions_field_view_access($field_name, $entity_type, $entity, $account) {
// Check if user has access to view this field in any entity.
if (user_access('view ' . $field_name, $account)) {
return TRUE;
}
// If the user has permission to view entities that they own, return TRUE if
// they own this entity or FALSE if they don't.
if (user_access('view own ' . $field_name, $account)) {
return _field_permissions_entity_is_owned_by_account($entity, $account);
}
return FALSE;
}
?>
Ich bin für jede Hilfe dankbar.
- Anmelden oder Registrieren um Kommentare zu schreiben
Versuche hook_form_alter
am 24.03.2015 - 09:49 Uhr
Meistens reicht es, den Zugriff innerhalb des Standard-Node-Bearbeitungs-Formulars zu steuern. Mit "global $user" kommt man an den aktuellen Benutzer und über das Node-Objekt kann man sehr dynamisch die Bearbeitungs-Möglichkeiten der einzelnen Formular-Felder steuern.
# DrupalCenter-Moderator # Mitglied im Drupal e.V. # https://www.drupal.org/u/c-logemann
# CTO der Nodegard GmbH: CMS Security & Availability Operations / Wir unterstützen IT-Abteilungen, Agenturen, Freiberufler:innen
mchott schrieb Es gibt dafür
am 24.03.2015 - 11:35 Uhr
Es gibt dafür ja diesen hook_field_access, aber ich verstehe nicht so recht, wie ich den anwende, bzw. glaube ich, dass dies nur innerhalb von Modulen funktioniert. Ist dem so?
Naja, da du den Terminus hook ja durch einen Modulnamen ersetzen musst, wird das so nicht funktionieren. Allerdings gibts da ja auch die function field_access(), die bei einem Request auch aufgerufen wird, wenn du die in einen Block packst. Allerdings: Das ist ein riesen Murcks!. Warum schreibst du für deine speziellen Anforderungen denn nicht ein kleines custom Modul. Da reicht doch eine mymodule.info und eine mymodule.module Datei völlig aus.
Der springende Punkt ist ja eigentlich: Wie prüfst du, ob ein User bezahlt hat?
Dann in der mymodule.module Datei in etwa so:
<?php
MY_MODULE_field_access(view, $field, $entity_type, $entity, $account) {
if($account->status_bezahlt == FALSE) {
if($field['field_name'] == 'premium_field_1') {
return FALSE;
}
else if($field['field_name'] == 'premium_field_2') {
return FALSE;
}
}
}
?>
Eine Alternative wäre vllt. auch eine Premium Rolle anzulegen und bei erfolgter Zahlung per Rules diese Rolle zuzuweisen. Dann könntest du einfach mit dem Field_Permission Modul arbeiten.
Jondos Digital
Mein eigenes Modul schreibe
am 25.03.2015 - 12:06 Uhr
Mein eigenes Modul schreibe ich nicht, weil ich mir einbilde und mehr ist es derzeit nicht, dass ich das nicht kann. Ich mache da ja noch einiges mehr, was aber alles recht überschaubar ist. Vielleicht probier ich es einfach mal aus?!
In meinem "Wirtschaftssystem" merke ich mir die Uid von Drupal zu einer Buchung. Damit kann ich beim Aufruf schnell sehen, ob der User bezahlt hat.
DANKE für die Info..ich werde es mal mit dem eigenen Modul versuchen und berichte dann.
Was den Murks angeht..leider bin ich da sehr pragmatisch. Wenn es performant und wartbar ist, zudem noch gut aussieht, dann ist es für mich okay. Die Integration des Wirtschaftssystems ist ohnehin eine frickelige Arbeit, aber sie ist entstanden, als mich das Anpassen von den fertigen Modulen nur noch geärgert hat.
LEIDER funktioniert es nicht
am 01.04.2015 - 09:48 Uhr
Hallo,
jetzt habe ich mein Modul geschrieben :-) war recht einfach und mein erster Testfall ist ein einfacher hook_node_access().
Es geht um ein Node, welches für den User eigentlich NICHT freigegeben ist. Im ersten Ansatz wollte ich den pauschal freigeben.
<?php
function super_node_access($node, $op, $account) { return NODE_ACCESS_ALLOW; }
?>
Aber der Node ist dennoch nicht freigegeben. Nun meine eigentliche Frage. Mein Modul soll ja eigentlich die Entscheidung eines anderen Moduls überschreiben. Ich verwende eigentlich TAC für die Zugangskontrolle. Da ein einmal gesetztes DENY mit dem ALLOW nicht aufgehoben wird..so scheint es mir..müsste ich dann die Reihenfolge beeinflussen oder das von TAC erlaubte dann beschränken (also nicht freigaben).
du müsstest innerhalb des
am 01.04.2015 - 10:16 Uhr
du müsstest innerhalb des hook_node_access() noch angeben, um welchen node(type), um welche Operation - z.Bsp.
$op = view
und um welche User(Rolle) es sich handelt. Dann kannst du meines Wissens den Zugang auch überschreiben. Die notwendigen Infos bekommst du mit:dpm($node);
dpm($account);
wenn das Devel Modul installiert ist.
Jondos Digital
Du meinst aber nicht eine
am 01.04.2015 - 14:11 Uhr
Du meinst aber nicht eine Abfrage wie diese hier
<?php
if($op == 'view' && $account->uid == 60) { .. }
?>
Das hatte ich probiert und weil es nicht ging, wollte ich es mal mit der Brechstange versuchen und pauschal alles erlauben, was ich eigentlich mit dem TAC verboten hatte. Das scheint nicht der rechte Weg. Jetzt habe ich aber auch mal einen umgekehrten Weg versucht und es per TAC freigegeben, um es dann zu verbieten...erfolglos.
Mein Fehler..was sonst :-)
am 02.04.2015 - 09:25 Uhr
Also da ich noch nie ein Modul gebaut habe, war mir eines nicht klar:
- Ich habe die nötigen Dateien erstellt
- dann habe ich zum einfachen Test die Funktion "mymodule_init()" eingebaut
- dann das Modul aktiviert
- und mich dann gewundert, warum alle weiten hook´s einfach nicht laufen wollten
Jetzt habe ich bemerkt, dass man das Modul einfach neu aktivieren muss, weil er scheinbar nur beim Aktivieren prüft, welche hook´s ich verwende und dann auch nur diese aufruft, was ja Sinn macht. War mir aber nicht klar. Da es eher zufällig war, habe ich viel gelesen und dabei gelernt, dass man besser einen hook_node_grants und hook_node_access_records implementiert, weil man dann ein ganzen Node steuern kann. Wenn es wirklich ein Feld sein muss, dann geht es wirklich so leicht:
<?php
function super_field_access($op, $field, $entity_type, $entity, $account) {
$payed = false; // wird bei mir über die Datenbank ermittelt .. hier nur der allgemeine Teil
if ($field['field_name'] == 'field_primecontent' && $op == 'view' && $payed == false) {
return FALSE;
}
}
?>
DANKE!
Das war wohl ein Cache-Problem
am 02.04.2015 - 13:25 Uhr
Jetzt habe ich bemerkt, dass man das Modul einfach neu aktivieren muss, weil er scheinbar nur beim Aktivieren prüft, welche hook´s ich verwende und dann auch nur diese aufruft, was ja Sinn macht.
Das stimmt so nicht. Sonst würden Modul-Update häufig schief laufen und aus eigener Programmiere-Erfahrung kann ich sagen, daß es nicht nötig ist ein Modul zu deaktivieren und wieder zu aktivieren, um neue Hooks anzusprechen. Allerdings macht es wohl Sinn, daß Dupal hier ein Cache verwendet, der dann neu aufgbaut wird, wenn man module aktiviert oder deaktiviert.
# DrupalCenter-Moderator # Mitglied im Drupal e.V. # https://www.drupal.org/u/c-logemann
# CTO der Nodegard GmbH: CMS Security & Availability Operations / Wir unterstützen IT-Abteilungen, Agenturen, Freiberufler:innen