[Risolto] Permettere Visualizzazione In Base A Un Parametro

Risolto errore relation…sbagliavo in ‘id_agenzia’ … il campo è ‘agenzia_id’

Corretta la relazione many_many, non da più problemi.

Resto in attesa per filtrare il tutto e far si che la tabella cap_agenzia (che relaziona cap_gestiti e agenzia) si popoli con gli id che riceve dalle due tabelle.

che depressione, non sono neppure (più) sicuro che la relations funzioni. E’ vero, non mi da errori, ma qualunque user loggato, può vedere e modificare i valori della tabella e non è quello che voglio.

Nessuno oltre al gentilissimo realtebo può darmi una mano per uscire fuori da questa situazione?? Perfavore !!!

Nessuna novità?? :(

Innanzitutto scrivi qual è il problema che hai ora,

possibilmente con qualche riga di codice così si può

sapere a che punto preciso sei arrivato.

Ciao Fabrizio e grazie dell’ interessamento. Avrai sicuramente intuito che sono novizio per quanto riguarda yii.

Sono al punto che il codice delle relazioni viene eseguito e vedo i Telegrammi. Il codice che ho nel Controller "Telegramma" alla action index è questo:

public function actionIndex()

{


	


	$dataProvider=new CActiveDataProvider('Telegramma');


	$user_id = Yii::app()->user->id;


	$user = User::model()->findByPk($user_id);


	$user_agency = $user->agenzia;


	$enabled_cap_list = $user_agency->cap_gestiti;


	$enabled_cap_array = CHtml::listData($enabled_cap_list, "id","id");


	$this->render('index',array(


		'dataProvider'=>$dataProvider,


	));


	//Controllo il ruolo di accesso


	echo Yii::app()->user->id;


	if(Yii::app()->user->checkAccess("admin"));


	


}

e la query che esegue è questa:

Querying SQL: SELECT cap_gestiti.id AS t1_c0, cap_gestiti.agenzia

AS t1_c1, cap_gestiti.cap_gestiti AS t1_c2, cap_gestiti.comune

AS t1_c3, cap_gestiti.provincia AS t1_c4, cap_gestiti.regione

AS t1_c5 FROM cap_gestiti cap_gestiti INNER JOIN cap_agenzia

cap_gestiti_cap_gestiti ON

(cap_gestiti_cap_gestiti.cap_gestiti_id=:ypl0) AND

(cap_gestiti.id=cap_gestiti_cap_gestiti.agenzia_id)

Ora io vorrei che nella vista venissero filtrati i telegrammi in base a un parametro che permetta visualizzazione e modifica solo da parte dell’ agenzia che ha in gestione il cap di destino.

Mi spiego meglio:

Agenzia 1 = cap gestito 08028

Agenzia 2 = cap gestito 94011

e cosi via. Ogni Agenzia ha un cap in gestione. Tutte le agenzie possono inviare telegrammi, ma nella vista index vorrei che ogni agenzia vedesse e potesse modificare (lo stato Consegnato - Non consegnato) solo i telegrammi che sono diretti verso il cap che la stessa ha in gestione. Non riesco a creare questo filtro. Infatti chiuque può vedere e esitare tutti i telegrammi e non solo quelli che appartengono alla propria agenzia.

Mi stava aiutando realtebo…ma è svanito nel nulla e non riesco a creare questo filtro o criterio di visualizzazione. Questo è il problema che mi sta facendo uscire di testa. realtebo ha detto che era una cosa facile…ma nonostante continui a leggere guide su guide e vari forum non riesco a venirne fuori.

Innanzitutto facciamo un pò di ordine.

Le tue tabelle dovrebbero essere le seguenti (le ho riprese da un precedente post):

C’è già qualcosa che non va.

Perchè

Agenzie:


  • id

  • id_cap : (ogni agenzia può gestire un solo cap, giusto?)

  • … (altri campi descrittivi)

Cap:


  • id

  • … (altri campi descrittivi)

Telegrammi:


  • id

  • id_cap (un telegramma è associato ad un solo cap, giusto?)

  • … (altri campi descrittivi)

User:


  • id

  • id_agenzia (quindi l’utente essendo collegato ad una sola agenzia, può gestire un solo cap) ?

E’ così la struttura reale?

Se puoi metti anche la lista dei campi di ciascun model e le relations, così si capisce bene cosa hai fatto.

Si Fabrizio, la struttura è più o meno questa. Anche se ho cambiato le tabelle…non sono più quelle dell’ inizio del post.

Le tabelle che hai riportato tu prese dall’ inizio del post …le ho cambiate per provare a fare come mi stava indirizzando realtebo) quindi le tabelle che ho adesso sono:

user = id, username, password, session, data_registrazione

agenzia = id, nome, codice, nome_completo

cap_gestiti = id, agenzia, cap_gestiti, comune, provincia, regione

cap_agenzia = agenzia_id, cap_gestiti_id

telegramma = id, nome, cognome, indirizzo, cap, citta, provincia etc.

Ovviamente ogni Telegramma è associato a un solo cap, perchè quando un "utente" (anche un utente registrato che si collega al sito) compone un nuovo telegramma, lo stesso telegramma avrà un cap di destino.

Esempio:

Nome : Fabbrizio

Cognome: Caldarelli

Indirizzo: Via tua n. 12

Cap: 00143 = parametro che dovra far capire a yii che quel cap è gestito dall’ “Agenzia” (id 1) che ha come utenti (utente 1, utente 2 etc) e che sono questi utenti che potranno modificare l’ esito del telegramma (consegnato - non consegnato).

Citta: Roma

Provincia: Rm

altri campi come : N° parole, prezzo, info utili per consegna, etc etc.

Ora devo trovare il modo di filtrare i telegrammi in maniera tale che (come detto prima) nella index “Telegramma” ogni agenzia possa prendere in carico (vedere e esitare) i telegrammi indirizzati al cap che la stessa gestisce. Dobe sto toppando ;) ? Non riesco a venirne fuori!!!

Allora, riguardo le tabelle:

user : non manca l’id_agenzia, cioè l’agenzia a cui l’utente è collegato?

agenzia: ma l’agenzia non è associata ad un cap? Quindi non manca il campo id_cap?

cap: Non manca la tabella dei CAP ?

cap_gestiti : A che serve se l’agenzia al massimo può essere associata ad un solo CAP ?

cap_agenzia : A che serve se l’agenzia al massimo può essere associata ad un solo CAP ?

telegramma: Io metterei id_cap piuttosto che cap, visto che hai la tabella dei cap normalizzata;

Quindi se l’utente fosse collegato all’agenzia e se l’agenzia ed i telegrammi avessero un campo id_cap,

per sapere quali telegrammi sono collegati all’utente (e quindi su cui lui può lavorare), dal model User avresti questo elemento nelle relations:




    'agenzia' => array(self::BELONGS_TO, 'Agenzie', 'id_agenzia'),

    'telegrammi' => array(self::HAS_MANY,'Telegrammi',array('id_cap'=>'id_cap'),'through'=>'agenzia')



Quindi una volta ricavato l’utente con:




$utente = User::model()->findByPK( Yii::app()->user->id );

$telegrammi = $utente->telegrammi;



in $telegrammi hai i telegrammi che l’utente a lui associati (attraverso l’agenzia).

Ok Fabrizio sei stato chiarissimo e te ne sono grato.

Ricreo tutto il database come dici tu e provo ad usare il tuo procedimento.

Aquanto ho capito dovrei agire in questo modo…dopo aver creato le tabelle:

Relaziono

User a Agenzia tramite id_agenzia (BELONGS_TO)

Agenzia a Cap tramite id_cap (HAS_ONE)

Telegramma a Cap tramite id_cap (BELONGS_TO)

Giusto o sono ancora fuori strada??

E’ giusto.

La cosa importante è che sei certo che un’agenzia può essere associata ad un solo cap. E se un giorno ci fosse l’esigenza che un’agenzia gestisca più cap? E’ possibile?

Altrimenti quello che hai scritto è giusto.

  • User contiene id_agenzia (quindi nel model di User fai un BELONGS_TO ad Agenzie tramite id_agenzia);

  • Agenzia contiene id_cap (quindi nel model di Agenzie fai un BELONGS_TO a Cap tramite id_cap);

  • Telegramma contiene id_cap (quindi nel model di Telegrammi fai un BELONGS_TO a Cap tramite id_cap);

Non capisco perchè hai scritto

Perchè per adesso ogni agenzia gestirà un solo cap…non avevo pensato all’ eventualità futura…però alla fine usando la tua soluzione (1 agenzia piu cap in gestione) sarebbe buono per un ampliamento futuro, xchè non dovrei modificare nulla. Quindi tu mi consigli anche in questa relazione di usare BELONGS_TO?

La tabella cap_agenzia posso anche eleminarla giusto? in questo caso non ci serve :-/

In una soluzione più generale, dove un’agenzia può gestire più cap,

devi creare una tabella 1:molti, del tipo:

agenzie_cap


  • id

  • id_agenzia

  • id_cap

Dopodichè, all’interno del model Agenzie, per avere la lista dei model cap collegati devi mettere nel relations




'agenzieCap' => array(self::HAS_MANY,'AgenzieCap', 'id_agenzia'),

'cap' => array(self::HAS_MANY','Cap', array('id_cap','id'), 'through' => 'agenzieCap')



La prima relazione ti dice che l’agenzia è collegata con il model (e quindi la tabella agenzie_cap) AgenzieCap attraverso la chiave id_agenzia;

La seconda relazione ti dice che i cap sono dalla tabella Cap in relazione con la relazione agenzieCap.

Cioè:

agenzie -> agenzieCap (tramite agenzie::id = agenzieCap::id_agenzia ) -> cap ( tramite cap::id = agenzieCap::id_cap)

spero sia tutto chiaro

Sei stato STRAchiarissimo e di questo te ne sono veramente grato.

Quindi è giusta la tabella che abbiamo creato con realtebo cap_agenzia che contiene proprio cap_id e agenzia_id. La relazione l’ avevo inserita nel model Agenzia in questo modo:

‘cap_gestiti’=>array(self::MANY_MANY, ‘CapGestiti’, ‘cap_agenzia(cap_gestiti_id, agenzia_id)’),

Ovviamente CapGestiti perchè avevo quella tabella nel database.

Ora provo a realizzare il tutto e poi ti faccio sapere…per correttezza e se serve posso postare anche il codice che magari potrebbe essere utile ad altri utenti.

Bimba permettendo…mia figlia…se riesco implemento tutto immediatamente e stasera posto il risultato.

Grazie ancora del tuo sapere Fabrizio °___°

Ultima cosa: eviterei nomi poco chiari come "cap_gestiti" … "agenzie_cap" o "cap_agenzie" sono sicuramente più evidenti e chiari.

Ultima domanda…mannaggia!!! Nella tabella Telegramma abbiamo inserito un campo id_cap.

Un utente non sarebbe mai in grado di utilizzare questo campo perchè non conosce l’ id del cap di destino. Se metto il campo hidden come faccio a fare capire a yii che quel telegramma con cap 08028 va a quella data agenzia? Il campo cap_id servirebbe se uno conoscesse l’ id del cap e potrebbe inserirlo…o funziona anche se lascio il campo hidden??

Es: nella creazione del cap 00156 io che l’ ho creato so che il suo id è (ipotetico) 10, ma l’ utente “normale” (non admin) non sa che quel cap ha quell’ id!!!

Dammi 2 schiaffi se sto dicendo cazzate ;D ti autorizzo!!!..yii mi sta bruciando il cervello!!! Me lo dice anche mia moglie mannaggia :D :o

Nella compilazione del telegramma, l’utente normale avrà un from con tutti i campi da compilare.

Per quanto rigurda il CAP, avrà a questo punto un menù a discesa ( una select per intenderci ) vincolato agli elementi della tabella CAP.

Cioè




$arrCap = Cap::model()->findAll();

$arrData = CHtml::listData( $arrCap, 'id', 'cap');


echo $form->dropDownList( $model, 'id_cap', $arrData);



Eccomi di nuovo…ho fatto tutto, ma qualsiasi utente loggato può vedere e modificare i telegrammi destinati ad altre agenzie che non siano la sua :( uff ma xchè non riesco che @@ . Relation:

Agenzia:

public function relations()


{


	return array(


	


	'cap_agenzia' => array(self::HAS_MANY,'CapAgenzia', 'id_agenzia'),


    'cap' => array(self::HAS_MANY,'Cap', array('id_cap','id'), 'through' => 'cap_agenzia')


	


	);


}

Telegramma:

public function relations()

{


	return array(


	


	'cap'=>array(self::BELONGS_TO, 'Cap', 'id_cap'),


	


	);


}

User:

public function relations()

{


	return array(


	


	'agenzia'=>array(self::BELONGS_TO, 'Agenzia', 'id_agenzia'),


	'telegramma' => array(self::HAS_MANY,'Telegramma',array('id_cap'=>'id_cap'),'through'=>'agenzia')


	


	);


}

Questa e l’ actionIndex nel model Telegramma

/**

 * Lists all models.


 */


public function actionIndex()


{


	$utente = User::model()->findByPK( Yii::app()->user->id );


    $telegramma = $utente->telegramma;


	$dataProvider=new CActiveDataProvider('Telegramma');


	$this->render('index',array(


		'dataProvider'=>$dataProvider,


	));


}

Non riesco a fare ciò che dovrei fare…stò sbagliando io qualcosa???

Il model Cap non ha relazioni e il model CapAgenzia non ha relazioni.

Questa è la query inputata (almeno credo)

Querying SQL: SELECT telegramma.id AS t1_c0, telegramma.nome_mitt

AS t1_c1, telegramma.cognome_mitt AS t1_c2,

telegramma.indirizzo_mitt AS t1_c3, telegramma.civico_mitt AS

t1_c4, telegramma.cap_mitt AS t1_c5, telegramma.citta_mitt AS

t1_c6, telegramma.provincia_mitt AS t1_c7, telegramma.stato_mit

AS t1_c8, telegramma.nome_dest AS t1_c9,

telegramma.cognome_dest AS t1_c10, telegramma.indirizzo_dest AS

t1_c11, telegramma.civico_dest AS t1_c12, telegramma.id_cap AS

t1_c13, telegramma.citta_dest AS t1_c14,

telegramma.provincia_dest AS t1_c15, telegramma.stato_dest AS

t1_c16, telegramma.parole AS t1_c17, telegramma.prezzo AS

t1_c18 FROM telegramma telegramma LEFT OUTER JOIN agenzia

agenzia ON (agenzia.id_cap=telegramma.id_cap) WHERE

(agenzia.id=:ypl0)

Devo inserire qualcosa nell’ access rules??? Li io ho inserito i ruoli che gestisco con rights. Quindi Amministratore e Operatore. Ma non riesce a filtrare…credo che a questo punto sono io a sbagliare qulcosa ma non capisco cosa ufff

Ho notato che nella tabella Telegramma non si popola il campo cap_id grazie al quale si dovrebbero visualizzare i telegrammi destinati alla agenzia che gestisce quel cap. Uhm…ricontrollo un attimo il menu dal quale selezioni il cap e vedo se riesco a fare popolare quel campo.