Download abilitato solo agli amici (utilizzando User_Relationship)

31 contenuti / 0 new
Ultimo contenuto
Download abilitato solo agli amici (utilizzando User_Relationship)

Ciao a tutti. Vorrei sapere se è possibile fare la seguente cosa:
Ho un tipo di contenuto che possono creare i miei utenti; questo contenuto ha un campo "file upload" dove possono caricare un file zip, quando viene creato il nodo, viene stampato anche il link di download del file zip. Ora sono riuscito a settare solo il fatto che il download è abilitato solo agli utenti, io però vorrei che questo download lo possano fare solo gli amici dell'utente che ha creato il nodo dov'è presente il link di download.

modifica i permessi

i permessi non includono il download dei file e soprattutto i permessi sono relativi agli utenti non relativi agli amici degli utenti

Il modulo che hai usato per gli amici non ha questi permessi?
Prova a farlo con le viste

no perchè il modulo crea delle relazioni tra utenti però non è un ruolo utente quindi il permesso non si puo modificare. Potrei farlo con le viste o piu semplicemente un controllo in php, però se un utente B, amico dell'utente A che ha creato il contenuto, prende il link di download e lo da a un altro utente del sito (non amico di A) puo comunque scaricare il file

E se l'utente A carica il file su un altro hosting e da il link esterno all'utente B l'utente B può scaricare il file....

si certo però farlo è illegale, puoi anche acquistare un film online e poi caricarlo su siti di hosting ma è sia illegale e inoltre ti ci devi anche mettere. Comunque sono ragionamenti che ho gia fatto. Qualcuno puo darmi una mano?

qualcuno puo aiutarmi? posso almeno sapere se è possibile farlo?

Ciao supergnomo,
prima di tutto il download dei file dal sito deve essere impostato come privato, altrimenti puoi mettere tutti i controlli che vuoi, ma se l'utente C viene a conoscenza del link si scarica il file anche senza essere amico di nessuno (anche senza essere registrato al sito) ;-)
Fatto questo implementi in un tuo modulo l'hook_file_download($filepath), questo hook è chiamato da drupal tutte le volte che utente tenta di fare un download (privato) di un file. Qua controlli l'utente che ha caricato il file, l'utente che sta cercando di scaricarlo e se sono amici ritoni un array di header (prob anche vuoto), altrimenti -1.

Luca

Grazie mille luca, finalmente una soluzione sensata. Ora proverò questa soluzione dell'hook. Comunque il download è gia privato, infatti se non sei utente non fa scaricare.

scusate se disturbo ancora, luca potresti darmi un esempio un po piu concreto? ho provato a cercare in giro per internet però non ho capito bene come utilizzare quella funzione hook_file_download($filepath)

supergnnomo, il problema che hai è nel definire i controlli da fare o a gestire cosa fare dopo i controlli?

Per il secondo problema, la documentazione della funzione è chiara: http://api.drupal.org/api/drupal/developer--hooks--core.php/function/hoo...

Quote:
If the user does not have permission to access the file, return -1. If the user has permission, return an array with the appropriate headers. If the file is not controlled by the current module, the return value should be NULL.

grazie pinolo, il problema è nel gestire cosa fare dopo i controlli. Allora nel caso non abbia i permessi ok stampo qualcosa del tipo "non hai i permessi" però nel caso abbia il permesso come gestisco quell'array che mi restituisce? Cioè io mi aspetterei che mi restituisca il path del file a video. Quell'array che mi restituisce in caso di permesso valido cosa contiene? e come si utilizza?

ho provato a implementare la funzione hook_file_download($filepath)

e mi da questo errore:

user warning: Table 'miosito.fileupload' doesn't exist query: SELECT filemime FROM fileupload WHERE filepath = 'sites/default/files'

l'ho copiata dal link che mi hai dato.

L'array, come dice la documentazione, contiene gli header da inviare per il trasferimento HTTP del file. Nell'esempio nella documentazione, viene fornito il MIME type. Non credo sia indispensabile (credo che i MIME type più comuni siano già coperti dalla negoziazione tra browser e Apache), quindi forse puoi restituire un array vuoto.

Prova a sostituire fileupload con "files" nella query. Inoltre, il filepath è il percorso completo con il nome del file, quindi la tua query non troverebbe comunque nulla.

Ciao,
in un'installazione di drupal standard la tabella fileupload non esiste..l'hai creata tu?
Per quanto riguarda cosa ritornare, deve essere

return -1;

se l'utente non può scricare il file, oppure

return array();

se lo può scaricare, a gestire gli errori ci pensa Drupal!

Grazie mille per le risposte. La tabella fileupload non l'ho creata io, praticamente io ho solamente fatto un campo cck dove l'utente fa l'upload, successivamente ho modificato la visualizzazione nel nodo e ho messo URL path, quindi nella stampa mi esce l'url del file, infatti se lo copio mi fa scaricare il file. Ora io in php ho assegnato alla variabile $filepath appunto il percorso che mi stampa il campo cck. Forse la tabella {fileupload} è generica, dovrei invece mettere la tabella dov'è presente il campo cck, però non saprei qual'è.

vi faccio vedere come ho fatto. (in questo modo non da piu errori sulla query).

<?php
function hook_file_download($filepath) {
global
$user;
  if (
$filemime = db_result(db_query("SELECT filemime FROM {files} WHERE filepath = '%s'", file_create_path($filepath)))) {
    if (
$user->uid==4 | $user->uid==1) {
      return array(
'Content-type:' . $filemime);
    }
    else {
      return -
1;
    }
  }
}
?>

<?php
$filepath
=$node->field_(campo con url del file)[0]['view'];
hook_file_download($filepath);
?>

Il problema rimane sempre, sicuramente è per come lo sto utilizzando.

hook_file_download non la devi chiamare tu, la chiama drupal quando l'utente clicca sul link del download :-)
Prova a farti stampare il valore di $filepath nella funzione, oppure usa un debugger per vedere cosa vale.
La funzione dovrebbe essere così:

<?php
function modulo_file_download($file) {
global
$user;
$filepath = file_create_path($file);
$fid = db_result(db_query('SELECT f.fid FROM {files} f WHERE f.`filepath` = "%s"', $filepath));
if(
$fid può essere scaricato) {
return;
} else {
return -
1;
}
}
?>

e poi basta, nn hai bisogno di scrivere altro codice

Grazie ancora per la pazienza luca :). Io ho adattato la funzione che mi hai scritto in questo modo:

<?php
function prova_file_download($file) {
global
$user;
$filepath = file_create_path($file);
$fid = db_result(db_query('SELECT f.fid FROM {files} f WHERE f.`filepath` = "%s"', $filepath));
if(
$user->uid==4) {
return
$filepath;
  }
  else
  {
return -
1;
  }
}
?>

Però il problema persiste, ovvero se l'utente che ha il "potere" di scaricare il file, copia il path di download e lo da a un altro utente del sito questo puo tranquillamente scaricare. Ho provato anche con la soluzione di pinolo ma non mi ha dato risultati neanche quella. Sicuramente sto sbagliando qualcosa ma solo perchè non capisco come drupal gestisca queste cose. Cioè ogni volta che un utente cerca di scaricare qualcosa, fa partire la funzione "prova_file_download"? Come fa a sapere che deve utilizzare questa funzione?

Ciao,
drupal chiamerà questa funzione al download di un file privato solo se è messa all'interno di un modulo che si chiama "prova", correttamente installato ed abilitato. Tu dove l'hai messa?
Per il resto, fai una query per ottere l'id del file che andrà scaricato, poi però non lo usi e controlli solo che l'id dell'utente che sta facendo il download sia uguale a 4.. quello che devi fare è cercare nel database quale utente ha caricato quel file (con una query sql), dopodiché controlli che id dell'utente loggato ($user->uid) sia quello di un suo amico: se questo è vero scrivi semplicemente "return;", altrimenti scrivi "return -1;"

Luca

ciao, ho provato anche questa soluzione, facendo un modulo con questa funzione, però drupal sembra non calcolarla per niente. E' possibile inserirla nel template di un tipo di contenuto, utilizzando content_templates? Oppure non funziona in questo caso? Chiedo scusa per il tempo che vi sto facendo perdere, però non capisco davvero come fare, se ci fosse qualche guida che conoscete la seguirei volentieri piu che farvi perdere altro tempo

Ciao,
no questa funzione può stare solo in un modulo che si chiama prova (quindi in un file che si chiama prova.module che sta in una cartella che si chiama prova, insieme al file prova.info). La guida drupal su come fare un modulo è qua:

http://drupal.org/developing/modules

Poi se riesci a mettere su un debugger (http://torino2010.drupalcamp.it/sessions/debugging-drupal) metti un breakpoint e vedi se la funzione viene chiamata.

Io non ci sono fino al 3 gennaio, spero tu riesca a risolvere il tuo problema prima :-)
Auguri (anche per le feste)!

grazie mille per gli aiuti che mi hai dato e molte grazie anche per gli auguri e ricambio! Proverò in questi giorni tra una mangiata e l'altra a vedere se risolvo. Grazie!

Lo so che sembra una stupidaggine, comunque (soprattutto tra una mangiata e una bevuta) dopo averlo creato, il modulo, ricordati di attivarlo :D

ci sono riuscito, grazie a tutti. Ora ho solo 2 problemi piu semplici che però non riesco a risolvere:
1) Dentro la nuova funzione hook devo fare un controllo sul node id ($nid), però se lo inserisco la query mi da errore perchè appunto non viene passato nella funzione, infatti se dichiaro la variabile $nid e le do un valore, il controllo funziona. Quindi come posso risalire a $nid?
2) Controllavo la tabella del modulo user_relationship. Però non ho capito come posso fare un controllo che mi verifichi se l'utente che sta visitando la pagina è amico di chi l'ha creata.

Grazie a tutti!

1) nel tuo modulo puoi accedere a arg() che restituisce (in base al parametro che gli passi) gli elementi del path interno di Drupal. In pratica, se stai visualizzando un nodo, arg(0) sarà "node" e arg(1) sarà il node ID.

ho provato a utilizzare arg(1) in questo modo:
db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE nid="%d" and uid="%d" ', arg(1), $user->uid))
ma mi da sempre lo stesso errore, come se non gli passasse il valore giusto, infatti se lo faccio manualmente, cioè se metto l'id del nodo (es. 7) , funziona tutto.

se io faccio questo controllo nella funzione hook_file_download

if (db_result(db_query("SELECT COUNT(*) FROM {comments} WHERE nid=%d and uid=%d", arg(1), $user->uid)) > 0)

mi restituisce sempre falso anche quando non lo è, mentre lo stesso controllo in una funzione non hook funziona. Ho provato a mettere al posto di arg(1) l'id di un nodo qualunque e il controllo funzionava. Com'è possibile?

Bene vedo che hai fatto passi avanti!
Temo che arg() chiamata all'interno di questo hook non avrà mai una valore in quanto non viene gestita durante la costruzione della pagina (è una supposizione, ma se nn ti funziona è probabile che sia così). Il lavoro lo devi fare sul file che ti arriva in input (che ha un senso visto che questo hook deve decidere se QUEL file può essere scaricato oppure no). Quindi devi fare una query con la tabella CCK che mette in relazione il nodo che contiene il file con il file stesso (e quello sta nella tabella files); fatto questo dovresti avere il nid del nodo in cui quel file è stato caricato. Dal nodo risali al uid del sul autore, infine controlli che $user->uid (ossia l'utente che è correntemente loggato) sia amico dell'autore del nodo che contiene il file (non ho mai usato user_relationship ma immagino che le info siano in una tabella gestita da questo modulo, anzi forse già esiste una funzione del tipo get_friend($uid)). Buona fortuna :-)

grazie mille luca e pinolo, ora funziona finalmente. Manca solo la query per fare il controllo se gli utenti sono amici.. per ora ho provato a farne una del genere, prendendo spunto da una views che fa piu o meno la stessa cosa

SELECT user_relationships.rid FROM {user_relationships} LEFT JOIN users users_user_relationships ON user_relationships.requestee_id = users_user_relationships.uid LEFT JOIN {users} users_user_relationships_1 ON user_relationships.requester_id = users_user_relationships_1.uid LEFT JOIN user_relationship_types user_relationship_types_user_relationships ON user_relationships.rtid = user_relationship_types_user_relationships.rtid WHERE (user_relationships.approved = 1) AND (user_relationships.requester_id = "%d") ' , $uid);

però per ora mi da errore, sto cercano di risolvere ora.