martedì 22 marzo 2011

PHP - FastCGI timeout

Script PHP particolarmente 'pesanti' possono andare in timeout ed interrompersi. Se si sta usando FastCGI e IIS7 (disponibile con Windows 7) è possibile aumentare questo timeout lanciando un comando dos e modificando il php.ini.

Aprire una console dos ed eseguire il seguente comando:

%windir%\system32\inetsrv\appcmd set config -section:system.webServer/fastCgi /[fullPath='C:\php\php-cgi.exe'].activityTimeout:600


modificare il parametro fullPath in modo da assegnargli il percorso di installazione del motore php (C:\php\php-cgi.exe) e il parametro activityTimeout assegnadovi un valore numerico che esprime i secondi (600, per avere un timeout di 10 minuti).

Quindi è possibile verificare che il timeout sia stato impostato correttamente semplicemente eseguendo il seguente comando:


%windir%\system32\inetsrv\appcmd list config -section:system.webServer/fastCgi


il quale nell'xml visualizzato dovremmo vedere il timeout di 600 secondi:

<system.webserver>
<fastcgi>
<application activitytimeout="600" fullpath="C:\php\php-cgi.exe">
<environmentvariables>
</environmentvariables>
</application>
</fastcgi>
</system.webserver>


Infine dobbiamo modificare il php.ini per eviare l'expire della pagina php è quindi la visualizzazione di una pagina bianca, per fare questo è sufficiente modificare il parametro max_execution_time.


max_execution_time = 600 ; Maximum execution time of each script, in seconds



NB: durante l'installazione di Drupal ho dovuto fare quanto descritto per poter terminarne il setup.

SQLServer - istruzione POWER

Recentemente mi e' capitato di dover cercare in una tabella "users" di SQLServer gli utenti con delle autorizzazioni specifiche (esempio 3 e 4).

Ad esempio,
la tabella users potrebbe essere cosi' configurata:

id int: id utente
name varchar(255): nome utente
auth int: autorizzazione


...e con il seguente contenuto:

idnameauth
1Mario3(00001000)
2Luigi4(00010000)
3Toad5(00100000)

In questi casi e' da evitare la select di tutti i record (select * from users) e il successivo controllo dei singoli bit via codice.
La soluzione invece piu' razionale prevede una select in grado di estrarre i soli record che hanno i bit che ci interessano impostati a 1.

In questi casi lo statement POWER e' l'istruzione che fa al caso nostro e la seguente istruzione sql e' quella che ci serve:

SELECT id, name, auth FROM users WHERE (POWER(2, ISNULL(auth, 0)) & 24 != 0)


Una volta eseguita visualizzera' il seguente risultato:

idnameauth
1Mario3
2Luigi4

Istruzioni per creare la tabella:
CREATE TABLE [dbo].[users]( [id] [int] IDENTITY(1,1) NOT NULL, [name] [varchar](50) NOT NULL, [auth] [int] NULL, CONSTRAINT [PK_users] PRIMARY KEY CLUSTERED ( [id] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]

LeadingZero - aggiungere degli zeri in testa ad una stringa

Questa funzione aggiunge degli zeri "0" in testa ad un stringa fino al raggiungimento di una lunghezza prefissata:


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Push "12345"
; Push 8
; Call LeadingZero
; Pop $0
; DetailPrint "result: $0" ; 00012345
Function LeadingZero
Exch $R2 ; zero
Exch
Exch $R1 ; number
Push $R0 ; result
Exch 2
Push $R3
StrCpy $R0 $R1

Loop:
StrLen $R3 $R0
${If} $R3 >= $R2
GoTo Exit
${ElseIf} $R3 > 32 ; exit if is more of 32 len
GoTo Exit
${EndIf}
StrCpy $R0 "0$R0"
GoTo Loop

Exit:
Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

!macro LeadingZero Res Num Zero
Push "${Num}"
Push "${Zero}"
Call LeadingZero
Pop "${Res}"
!macroend

!define LeadingZero "!insertmacro LeadingZero"

venerdì 18 marzo 2011

Editare un pdf

Cosa fare quando ci viene chiesto di scaricare un modulo pdf di compilarlo e di spedirlo via email. Ma questo una volta aperto con Acrobat Reader non ci permette di fare alcuna modifica?

Non ho ne stampante e ne scanner, che fare?
In questi casi Open Office ha un'estensione gratuita che si chiama PDF Import, questa una volta installata permette di convertire un pdf nel formato odt (word di openoffice).

Quindi quello che dobbiamo fare e' installare l'ultima versione di OpenOffice e procedere con l'installazione dell'estensione pdfimport.

Questi sono i link:
OpenOffice: OpenOffice
PDF Import: PDF Import extension

A questo punto non ci rimane che importare il pdf che apparira' in Draw (Word di OpenOffice) come un documento editabile, una volta modificato sara' possibile salvarlo nuovamente come pdf!

mercoledì 12 gennaio 2011

Conversione numerica da/a qualsiasi base

Riporto il codice autocostruito per NSIS al fine di eseguire delle conversioni numeriche da base decimale a qualsiasi altra base compresa tra 2 e 36.


Function DecToBX
Exch $R2 ; base
Exch
Exch $R1 ; number
Push $R0
Exch 2
Push $R3
StrCpy $R0 "" ; result

Loop:
System::Int64Op $R1 % $R2
Pop $R3

StrCpy $R3 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 1 $R3
StrCpy $R0 "$R3$R0"

System::Int64Op $R1 / $R2
Pop $R1

StrCmp $R1 0 0 Loop

Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

!macro DecToBX Res Num Base
Push "${Num}"
Push "${Base}"
Call DecToBX
Pop "${Res}"
!macroend

!define DecToBX "!insertmacro DecToBX"


Di seguito il codice per fare l'operazione inversa, ovvero convertire un numero da qualsiasi base numerica in decimale:


Function BXToDec
Exch $R2 ; base
Exch
Exch $R1 ; number
Push $R0 ; result
Exch 2
Push $R3
StrCpy $R0 0

Loop:
StrCpy $R3 $R1 1 0
${IndexOf} $R3 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" $R3
System::Int64Op $R0 * $R2
Pop $R0 ; vale -1 in caso di errore
System::Int64Op $R0 + $R3
Pop $R0
StrCpy $R1 $R1 "" 1
StrCmp $R1 "" 0 Loop

Pop $R3
Pop $R2
Pop $R1
Exch $R0
FunctionEnd

!macro BXToDec Res Num Base
Push "${Num}"
Push "${Base}"
Call BXToDec
Pop "${Res}"
!macroend

!define BXToDec "!insertmacro BXToDec"


La funzione BXToDec fa uso della macro IndexOf il cui codice si puo' recuperare dal seguente link: IndexOf source code

Esempio di utilizzo:

${DecToBX} $R0 0xF58DE 36 ; return LK2M
DetailPrint "result: $R0"

${BXToDec} $R0 "LK2M" 36 ; return 1005790 (0xF58DE)
DetailPrint "result: $R0"


Incrociano le due funzioni e' possibile fare una conversione da qualsiasi base numerica, ad esempio da base 16 a base 36:

${BXToDec} $R0 "F58DE" 16 ; return 1005790
${DecToBX} $R0 $R0 36 ; return LK2M
DetailPrint "result: $R0"


Entrambe le funzione non fanno alcun controllo sui parametri, ad esempio che la base sia nel range compreso tra 2 e 36.

Per verificare il risultato potete usare questo link: http://www.translatorscafe.com/cafe/units-converter/numbers/calculator/decimal-to-base-36

martedì 11 gennaio 2011

Aggiungere il supporto SourceSafe a PhpED

Deciso! Metto tutto su SourceSafe cosi' non mi rompo piu' le scatole a sincronizzare le modifiche dei sorgenti php. Il problema e' riuscire ad integrare SS con PhpED, l'ide che al momento e' in cima ai miei preferiti, anche se c'e' stato qualche vano tentativo di passare ad Eclipse.

Accedere alle variabili di ambiente di Windows e aggiungere alla PATH delle "Enviroment Variables -> System Variable" il percorso di installazione di SourceSafe, dove all'interno del folder dovra' essere presente il comando ss.exe:
C:\Program Files (x86)\Microsoft Visual SourceSafe;

Sempre nelle "Enviroment Variables -> System Variable" di Windows creare la voce SSDIR ed assegnarvi il percorso del file "srcsafe.ini", nel mio caso si trovava su un server in rete, quindi nel mio caso ho fovuto assegnarvi un indirizzo di questo tipo:
\\server_sourcesafe\Progetti\VSS

NB: e' possibile che prima di utilizzare PhpED per fare il CheckOut/CheckIn dei file di progetto si debba accedere alla cartella (SSDIR) via file system inserendo le credenziali se richieste.

Una volta preparate le due variabili di ambiente non ci rimane che aggiungere le voci di menu all'interno di PhpED:
- Selezionare Tools -> Settings -> Integration
- Premere il pulsante Add Menu, quindi editare il nome che si vuole dare alla nuova voce di menu contestuale. Per il checkout ho utilizzato "Check Out".
- Selezionare la voce di menu "Check Out" e premere Edit, quindi selezionare la voce Shell nella 'Execute with' e inserire come command line:
ss Checkout "$/SourceSafeProjectPath@RelFName@" -GL@Path@, dove '$/SourceSafeProjectPath' si riferisce al path del progetto in SS (valore adiacente alla label 'name' nelle proprieta' del progetto SS)
- Infine nelle opzioni selezionare 'Show this command in Workplace popup' e 'for files'

Proseguire aggiungendo le altre voci di menu "Check In" e "Undo Check Out" ripetendo i passi precedenti e evendo cura di modificare il comando di shell a seconda dei casi.
Qui sotto sono brevemente elencati i comandi SourceSafe in base alle funzionalita':

Check Out
ss Checkout "$/SourceSafeProjectPath@RelFName@" -GL@Path@

Check In
ss Checkin "$/SourceSafeProjectPath@RelFName@" -GL@Path@ -C

Undo Check Out
ss Undocheckout "$/SourceSafeProjectPath@RelFName@" -GL@Path@


Per conoscere i comandi riconosciuti da ss.exe fare riferimento al seguente link:
http://msdn.microsoft.com/en-us/library/003ssz4z%28v=vs.80%29.aspx

Mentre per le variabili contestuali utilizzabili nelle macro di PhpED, aprire l'help e andare alla seguente pagina:
Contents -> Customized PhpED -> Type of handlers and macros

mercoledì 29 dicembre 2010

Creare una feature per il deploy delle liste SharePoint

Ci sono diversi metodi per fare il deploy di una lista:
- salvare la lista come list template direttamente dall'interfaccia di SharePoint.
- scrivere una feature affinche' costruisca la lista interamente via codice.
- realizzare una feature definita "list definition".

Per un lavoro veloce le list defintion sono da preferirsi, non occorre scrive codice e non presentano il problema legato alla perdita dei riferimenti alle liste di lookup, come invece accade con le list template.

Per generare la feature possiamo utilizzare il tool "SharePoint Solution Generator", installato con il package "Visual Studio 2008 Extensions v1.3".



quindi selezionare l'icona 'List Definition', il site dove si trovano le liste, le liste che vogliamo esportare e infine confermare il salvataggio.


Il salvataggio crea per ogni lista una cartella, alcuni dei file contenuti in queste cartelle dovranno essere modificati per adattarli alle nostre esigente, questi sono: schema.xml e listdefinition.xml

Una delle modifiche prevede la riassegnazione delle liste di lookup, quindi dobbiamo aprire il file schema.xml e sostituire tutti gli attributi List dei Field di tipo Lookup o LookupMulti (rapresentati da dei guid) con il path della lista di lookup, ad esempio:

<Field Type="Lookup" List="Lists/LOOKUP_LIST"
<Field Type="LookupMulti" List="Lists/LOOKUP_LIST"


Un'altra modifica prevede l'assegnazione di un codice numerico univoco alla proprietà Type dello schema.xml e del file ListDefinition.xml, ad esempio: 10000.

Per chi fosse interessato alla descrizione degli elementi presenti nel file schema.xml puo' dare un'occhiata al seguente link: List Schema Elements


Se avete la necessita' di fare il deploy di una lista con il suo contenuto, potete usare il tool SPListInstanceGenerator che ho realizzato per esigenze personali (in fondo all'articolo e' possibile farne il download). Questo tool crea il file ListInstance.xml che andra' poi sostituito a quello presente nella cartella della lista corrispondente.
Il file xml generato dal tool non e' ben formattato, per cui prima di procedere consiglio sempre di riformattarne il contenuto. Procedere quindi caricando l'xml in Visual Studio, riformattare il file utilizzando la combinazione di tasti CTRL+A (per selezionare l'intero contenuto), CTRL+K e CTRL+F e infine salvare il file senza cambiarne il nome.
Se poi il contenuto dell'xml dovesse contenere dei caratteri speciali dovrete aver cura di incapsularli tra i seguenti tag:

<![CDATA[
...
]]>



Ci siamo quasi, una volta che le liste sono state definite non ci resta che aggiungere il file feature.xml al progetto, questo file infatti dice cosa e dove andrà installata la feature, e infine compilare il pacchetto wsp.

Il pacchetto wsp da utilizzarsi per il deploy puo' essere generato a mano editando un file ddf, il manifest e infine costruendo il file cab con il tool makecab, questo file non e' altro che un wsp.
In alternativa e' possibile installare il tool WSPBuilder e creare il progetto della feature direttamente da Visual Studio 2008.


Download:
Visual Studio 2008 Extensions v1.3
WSPBuilder
SPListInstanceGenerator