[R.I.A] Site Explorer in flex e PHP

Stato
Discussione chiusa ad ulteriori risposte.

cyd

Utente Silver
11 Giugno 2007
59
0
1
70
------------------------------------------
Autore : GreyFox
Linguaggi : ActionScript3,XML,PHP,HTML
Tempo : 2 giorni(lo sviluppo) 2 minuti(il tutorial)
-------------------------------------------
Ciao,innanzi tutto premetto che questo 'tutorial' analizza una semplice applicazione in flex,è da poco che ho iniziato con flex2 e postando questo spero che mi possiate dare anche un aiuto su come migliorare i vari script
e magari una mano per la LONTANA realizzazione di un web desktop utilizzando appunto flex,php,javascript e xml.

IL RISULTATO di questa prima applicazione,di cui tratteremo in questo post lo potete trovareQUI:
www.cybase.altervista.org/fxe.... (momentaneamente non disponibile)

Dunque iniziamo...
Innanzitutto ho creato in flex :
l'applicazione principale: FXEXPLORER.MXML,
il componente : icodir.mxml ossia l'icona delle directory
il componente: icofil.mxml l'icone dei files
il componente mniu.mxml ossia il menu
un piccolo foglio css: fexstyle.css

poi ho creato :
un xml per archiviare i contenuti: ico.xml
la pagina principale: index.html
la pagina per il filmato(autogenerata): fxexplorer.html
e la pagina php: manager.php

nella pagina principale(index.html) ho linkato l'apertura del popup contenente l'applicazione con il seguente codice:
Codice:
<script type="text/javascript">
function explore(){
window.open("fxexplorer.html","fxe","channelmode,resizable=false","width=702","height=494");
}
</script>
//.....il resto della pagina
<a href="javascript:explore()">Apri FlexSiteExplorer</a>
//...il resto

la pagina contenente il filmato è autogenerata,ma ci ho aggiunto la seguente funzione che consentira l'apertura delle pagine nella index:
Codice:
<script language="javascript" type="text/javascript">
function openDoc(fl){
opener.document.location=fl;
}
</script>

il file ico.xml possiamo lasciarlo vuoto.

il fexstyle.css,scritto giusto per risparmiare un pelo di spazio sarà:
Codice:
.appcb{
borderThicknessBottom:0;
borderThicknessLeft:0; 
borderThicknessRight:0;
borderThicknessTop:0;
headerHeight:0;
backgroundColor:#393f53;
backgroundAlpha:0.2;
cornerRadius:0;
shadowDistance:0;
}
.labs{
color:#ffffff;
fontSize:11;
fontFamily:verdana;
}
.pls{
color:#eff1f5;
cornerRadius:0;
fillAlphas:0.0, 0.0;
themeColor:#bfb8c5; 
}
dove appcb è lo stile dei pannelli , labs quello dei testi, pls dei pulsanti.

passiamo al php.
Nella pagina: manager.php ho scritto il seguente codice
PHP:
<?
$fxd="<dati>";

//---lettura directory--

if($_POST['richiesta']){
$directory=(string)$_POST['richiesta'];

$nf=0;
$nd=0;

if($dir = opendir($directory)) {

    $fxd.="<directory>".$directory."</directory><dirs>";
	$dirs = Array();
	$files = Array();

	while($file = readdir($dir)) {
            
       if($file != "." && $file != ".." && $file != 'fxexplorer.html' && $file!='fxexplorer.swf' && $file!='manager.php') {
               
             if(is_dir($directory . "/" . $file)) {
                  array_push($dirs,$file);
				 $nd++;
             }else{
                  array_push($files,$file);
				  $nf++;
             }
        }
 }
$i=0;
$j=0;

if($nd!=0){
while($i<$nd){
	$fxd.="<dir>".$dirs[$i]."</dir><peso>".filesize($directory.$dirs[$i])."</peso>";
	$i++;
}
}

$fxd.="</dirs><files>";

if($nf!=0){
while($j<$nf){
	$fxd.="<file>".$files[$j]."</file><peso>".filesize($directory.$files[$j])."</peso>";
	$j++;
}
}

$fxd.="</files><nd>".$nd."</nd><nf>".$nf."</nf></dati>";

}

closedir($file);
$log=@fopen('sys/ico.xml','w');
@fwrite($log,$fxd);
@fclose($log);
echo $fxd;
}
?>
il quale , 'letteralmente' , esegue lae seguenti azioni:
-inizializza il xml che conterrà i dati sul contenuto del sito,
-controlla se flex ha inviato il percorso ($_POST['richiesta']) dal quale estrarre i dati
-pone il numero di file e di cartelle trovati a '0' e aggiunge all'XML la directory corrente (quella richiesta da flex)
-controlla che la directory richiesta non appartenga a quelle non richiedibili e crea due ARRAY su cui posizionare i dati.
-apre la directory e ne estrae il contenuto,lo distingue in files e cartelle e per ogniuno di essi incrementa il rispettivo indicatore(files=$nf , dirs=$nd)
-con i due cicli 'while' compila i nodi del file xml (ico.xml) comprendendo il nome del file e il peso(filesyze(file)).
-aggiunge i nodi contenenti gli indicatori e chiude il file xml
-apre ico.xml (situato nella cartella sys) e ci scrive i nodi.

passiamo a flex:
Il file principale : fxexplorer.mxml l'ho creato con componenti statici e con una parte dinamica in actionscript3 che vedremo dopo.
la parte statica dell'applicazione è:
Codice:
PARTE 1:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" backgroundGradientColors="[#393e4f, #757d9b]" xmlns:local="*">
<mx:script>

LO VEDIAMO DOPO

</mx:script>

<mx:Style source="sys/fexstyle.css"/>

<mx:HTTPService concurrency="last" id="showFiles" method="POST" url="manager.php" showBusyCursor="true" fault="fallita('Richiesta http fallita');" result="setDati()" >
	<mx:request xmlns=""><richiesta>{richiesta}</richiesta></mx:request>	
</mx:HTTPService>
fin qua vediamo
-le proprietà dell'applicazione(nel tag <application>)
-l'importazione statica del foglio css
-L'inizializzazione della richiesta alla pagina PHP in cui sono presenti i collegamenti a funzioni nel caso di Fallimento e riuscita dello scambio di dati.(fault="fallita()" & result="setDati()")
Codice:
PARTE 2:

<mx:VBox x="1" y="1" verticalGap="2" creationComplete="showFiles.send()" >

 <mx:Panel width="700" height="60" styleName="appcb" layout="absolute" >
  <mx:ApplicationControlBar width="700" height="60"  cornerRadius="0"/>
  <mx:Label text="FlexSiteExplorer " fontSize="21" color="#a4a0ad" fontFamily="Arial" x="12" y="16"/>
  <mx:SWFLoader source="@Embed('sys/fxexplorer.swf')" x="530" y="5" />
 </mx:Panel>
 
 <mx:HBox horizontalGap="1" >
 <mx:Panel height="400" width="171" styleName="appcb" id="menus">
  <local:meniu id="mniu" visible="false"/>
 </mx:Panel>

  <mx:Canvas width="524" height="400"  backgroundColor="#848a9f" backgroundAlpha="0.2" >
 <mx:Tile id="desk" direction="vertical" horizontalGap="1" verticalGap="10" width="520" height="391" x="4" y="4"/>
  </mx:Canvas>
  
 <mx:Panel width="3" height="400" styleName="appcb" >
  <mx:ApplicationControlBar width="3" height="400"  cornerRadius="0"/>
 </mx:Panel>
 
 </mx:HBox>
 
 <mx:Panel width="700" height="30" styleName="appcb">
 	<mx:ApplicationControlBar width="700" height="30"  cornerRadius="0">
 	<mx:Label id="perc" text="" styleName="labs"/>
 	<mx:Button  height="26" cornerRadius="0" label="Homepath" alpha="0.37" click="richiesta='./';showFiles.send()"/>
 	<mx:Spacer width="400"/><mx:Label text="By GreyFox" styleName="labs"/>
 	</mx:ApplicationControlBar>
 </mx:Panel>
 
</mx:VBox>
</mx:Application>
Ossia il corpo statico dell'applicazione:
-'<mx:VBox ...' è il comp. VBOX principale la cui creazione invia la prima richiesta al manager.php,
-Il pannello in alto (il primo <mx:panel>) il quale contiene il titolo e il filmato swf di presentazione(<mx:SWFLoader ..ecc.. />)
-dopo la chiusura del panel c'è un 'HBOX' che conterra in layout orizzontale il menu e il 'desktop'.
-il 'panel subito dopo contiene il componente personalizzato MNIU.XML che vedremo
-il '<canvas>' contiene la griglia (<tile id="desk" .../>) che conterrà le icone.
-poi c'è un pannello che fa da bordo
-chiuso l'<HBox> c'è la barra di sotto
che contiene un campo di testo dinamico (<Label id="perc" ... />) il quale riporterà eventuali errori o il percorso corrente sul server e un pulsante(<Button .. label="Homepath" ../>) il quale setterà la variabile 'richiesta' su './' e la invierà a 'manager.php' che restituirà la directory principale.

Passiamo alla componente actionScript della pagina:
Codice:
<![CDATA[
//Importo le classi 
	import mx.controls.TextArea;
	import mx.controls.Spacer;
	import mx.rpc.events.ResultEvent;
	import mx.controls.Button;
	import mx.managers.PopUpManager;
	import mx.containers.TitleWindow;
	import flash.net.*;
	import flash.external.ExternalInterface;

//inizializzo le variabili

[Bindable] public var richiesta:String='./';
		   public var ext:String;
       	   XML.ignoreWhitespace=true
		   public var elenco:XML;
		   public var loader:URLLoader = new URLLoader();
		   
public function setDati():void{

//richiedo il file xml con i dati

var request:URLRequest = new URLRequest("sys/ico.xml");
loader.load(request);
loader.addEventListener(Event.COMPLETE, onComplete);

//Quando è completo eseguo la funzione setDati
		
function onComplete(event:Event):void{
		
   	var loader:URLLoader = event.target as URLLoader;
    elenco = new XML(loader.data);
    desk.removeAllChildren();//cancelliamo i files precedenti
//creazione Cartelle
if(elenco.nd!=0){
        for(var i:Number=0;i<Number(elenco.nd);i++){
        	var dir:icodir = new icodir()
        	dir.no=i;
        	dir.tipo='Folder';
        	dir.tit=String(elenco.dirs.dir[i]);
        	dir.peso=Number(elenco.dirs.peso[i]);
        	dir.percorso=String(elenco.directory);
        	dir.lnk=dir.percorso+dir.tit+'/';
        	desk.addChild(dir);
        	perc.text=dir.percorso
        	
    }
}
//Creazione icone dei Files

if(elenco.nf!=0){
 for(var j:Number=0;j<Number(elenco.nf);j++){
       var fil:icofil = new icofil()
       fil.no=j;
       //estensione
       var iof:Number=new Number(String(elenco.files.file[j]).indexOf('.'));
       ext=String(elenco.files.file[j]).substr(iof+1,String(elenco.files.file[j])
       .length-(String(elenco.files.file[j]).length-iof));
       fil.tipo=ext;
       //--
       fil.tit=String(elenco.files.file[j]);
       fil.peso=Number(elenco.files.peso[j]);
       fil.percorso=String(elenco.directory);
       fil.lnk=fil.percorso+fil.tit;
       desk.addChild(fil);
      }
}
//la 'barra di stato'
perc.text=richiesta;
}
//mi disconnetto
showFiles.disconnect();
}
//Funzione da eseguire quendo la richiesta fallisce
public function fallita(stringa:String):void{
perc.text=stringa;
}

//QUA CI SARANNO LE FUNZIONI PER APRIRE I FILES..LE VEDIAMO DOPO.

]]>

Questo codice è semplice e spiegato dai commenti:
importa le classi,inizializza le variabili,carica l'xml con i dati,crea per ogni dato riportato la rispettiva icona creando 2 componenti personalizzati:
icofil.mxml per i files e icodir.mxml per le cartelle.

vediamo entrambi i componenti:
Codice:
ICOFIL:
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" click="showAt()" doubleClickEnabled="true" doubleClick="openFile()" >
<mx:Script>
	<![CDATA[
	[Bindable] public var tit:String;
	[Bindable] public var peso:Number;
	[Bindable] public var percorso:String;
	[Bindable] public var lnk:String;
	[Bindable] public var no:Number;
	[Bindable] public var tipo:String;
	
public function showAt():void{

//passa le variabili al mniu.mxml(ossia il menu)
	parentApplication.mniu.visible=true;
	parentApplication.mniu.nom.text='Nome: '+tit;
	parentApplication.mniu.typ.text='Tipo: File '+tipo;
	parentApplication.mniu.pes.text='Peso: '+peso.toString()+' Bytes';
	parentApplication.mniu.lin.text='Link: '+lnk;
	parentApplication.mniu.per.text='Url: '+percorso;
	parentApplication.mniu.perc=lnk;
	parentApplication.mniu.tipo=tipo;
	parentApplication.mniu.addBtn('file',tit.toString(),lnk.toString());
}
//la funzione che aprirà il file situata nell'applicazione principale...lavediamo dopo.
public function openFile():void{
	parentApplication.openFile(lnk,tipo);
}

	]]>
</mx:Script>
<mx:HBox id="cont" horizontalGap="1" >
	<mx:Image  source="@Embed(source='sys/file.png')" height="40" width="40"  />
	<mx:VBox verticalGap="-2">
	<mx:Label id="titolo" text="{tit}" color="#ffffff" />
	<mx:Label id="tipos" text="{tipo}" />
	</mx:VBox>
</mx:HBox>
</mx:Box>
molto semplice...importa i valori da fxexplorer e ,sulla base di un corpo statico che è compreso da un'immagine e un titolo crea l'icona.
con il doppio click(vedi nei parametri del hbox principale) si aprira il file...

Codice:
ICODIR:
<?xml version="1.0" encoding="utf-8"?>
<mx:Box xmlns:mx="http://www.adobe.com/2006/mxml" click="showAt()" doubleClickEnabled="true" doubleClick="openFolder()" >
<mx:Script>
	<![CDATA[
	[Bindable] public var tit:String;
	[Bindable] public var peso:Number;
	[Bindable] public var percorso:String;
	[Bindable] public var lnk:String;
	[Bindable] public var no:Number;
	[Bindable] public var tipo:String;
	public function showAt():void{
	parentApplication.mniu.visible=true;
    parentApplication.mniu.nom.text='Nome: '+tit;
	parentApplication.mniu.typ.text='Tipo: '+tipo;
	parentApplication.mniu.pes.text='Peso: '+peso.toString()+' Bytes';
	parentApplication.mniu.lin.text='Link: '+lnk;
	parentApplication.mniu.per.text='Url: '+percorso;
	parentApplication.mniu.addBtn('dir',tit.toString(),lnk.toString());
	}
	public function openFolder():void{
	parentApplication.richiesta=lnk;
	parentApplication.showFiles.cancel();
	parentApplication.showFiles.send();
	}
	]]>
</mx:Script>
<mx:HBox id="cont" horizontalGap="1" >
	<mx:Image  source="@Embed(source='sys/folder1.png')" height="40" width="40"  />
	<mx:VBox verticalGap="-2">
	<mx:Label id="titolo" text="{tit}" color="#ffffff" />
	<mx:Label id="tipos" text="{tipo}"/>
	</mx:VBox>
</mx:HBox>
</mx:Box>
la stessa cosa...solo che chiama un'altra funzione specifica (openPage()) che invia una richiesta a manager.php con il proprio percorso.

passiamo a MNIU.mxml:
Codice:
<?xml version="1.0" encoding="utf-8"?>
 <mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml" >
 <mx:Script>
 	<![CDATA[
import mx.controls.Button;
 	
public var btn:Button;
public var perc:String;
public var tipo:String;
public var dirp:String;
public var p:String;

public function addBtn(tip:String,nome:String,per:String):void{
bt.label="Apri "+nome
if(tip=="file"){
	dirp='file';
}else if(tip=='dir'){
dirp='dir';
p=per
}
}
public function oFile():void{
if(dirp=='dir'){
	parentApplication.richiesta=p;
	parentApplication.showFiles.cancel();
	parentApplication.showFiles.send();
}else{
	parentApplication.openFile(perc,tipo)
}
}

 	]]>
</mx:Script>
<mx:ApplicationControlBar width="171" height="20"  cornerRadius="0">
<mx:Label text=":::Details:::" textAlign="center" styleName="labs" width="161"/></mx:ApplicationControlBar>
 <mx:Box id="tainer">
 <mx:Label id="nom" text="Nome: " styleName="labs"/><mx:Label id="typ" text="Tipo: " styleName="labs"/>
 <mx:Label id="pes" text="Peso: " styleName="labs"/><mx:Label id="lin" text="Link: " styleName="labs"/>
 <mx:Label id="per" text="Url: " styleName="labs"/>
 <mx:Button id="bt" width="171" height="20" styleName="pls" click="oFile()"/>
</mx:Box>
</mx:VBox>
Beh solita storia...inizializza le variabili e contiene il metodo
addBtn() che viene chiamato da icofil e icodir e a seconda del tipo che lo chiama(file o dicrectory) crea un pulsante apposito che eseguirà la funzione rispettiva.

Vediamo queste funzioni:
nel codice di fxexplorer.mxml aggiungiamo:
Codice:
public function openFile(file:String,ftipo:String):void{
if(ftipo=='txt' || ftipo=='js'){
//Definizione delle variabili necessarie ----------
var window:TitleWindow=new TitleWindow();
var testo:TextArea=new TextArea();
var closebtn:Button=new Button();
var spac:Spacer=new Spacer();
var tst:URLRequest=new URLRequest(String(file));
var filer:URLLoader=new URLLoader()
//Caricamento del file
	filer.load(tst);
	filer.addEventListener(Event.COMPLETE,okGo);
function okGo():void{
	testo.text=String(filer.data);
}
	window.title=file;
//Inizializzazione della visuale
	testo.width=475;testo.height=300;
	testo.editable=false;
	window.horizontalScrollPolicy='false';
	window.width=500;window.height=400;
	window.x=100;window.y=70;
	closebtn.label="Close";
	closebtn.styleName="pls";
//Creazuione popup
	window.addChild(testo);
	window.addChild(closebtn);
	PopUpManager.addPopUp(window,desk);
	closebtn.addEventListener(MouseEvent.CLICK,closepopup);
	
	function closepopup():void{
	PopUpManager.removePopUp(window);
	}

}else{
flash.external.ExternalInterface.call("openDoc",file.toString())
}
}

Il quale controlla che l'estensione sia sicura e apre il file, nel caso di un .txt o .js , in una popup(di flex) e nel caso di un'altra pagina, la apre tramite le funzioni nelle pagine html nella pagina madre(Index.html).

per ora niente dui particolarmente difficile...
spero che sia piaciuto a qualcuno(cosi come è adesso) seppur primitivo
e spero che a qualcuno stia salendo l'interesse per le ria con flex2 o 3...
i prossimi sviluppi( versione 0.2.5) saranno:
-ampliamento workspace
-possibilità di creazione,modifica e gestione dei files,
-altri metodi di archiviazione e visualizzazione dati,
-sistema di download-upload files,
-sistema di login e personalizzazione dello spazio,
-primi programmini(lettori multimediali ecc)
-browser

Se qualcuno vuole darmi una mano,come ho gia detto è benaccetto...
se vi interessano sorgenti ecc ditelo
sono accetti consigli
min***** che botta!

Ciao
GreyFox
 
volevo segnalare anke qst intanto ke ci sn..
http://examples.adobe.com/flex2/consulting/styleexplorer/Flex2StyleExplorer.html
 
Stato
Discussione chiusa ad ulteriori risposte.