Trasferimento o copia di blog wordpress 4.3.x tra server windows 2008

wordpress-logo-s

Obiettivo: trasferire e/o copiare  un blog wordpress  da un server Windows 2008 ad altro server Windows 2008.  Il trasferimento può far comodo anche per avere una copia in locale del blog.  Per poter effettuare l’operazione  è necessario l’accesso ai MySQL e alle cartelle delle web application nei  servers conivolti nel trasferimento. Se non si dispongono dei dati di accesso non resta che far ricorso al plugin per l’esportazione con i limiti del caso.  La versione di WordPress presa in considerazione è la 3.5.1. I servers utilizzati potrebbero essere sia Linux che Windows. Per quanto riguarda i databases MySQL è sufficiente che la versione sia 5.0 o successive. Un’articolata discussione di tutte le situazioni che si possono presentare quando si deve spostare un blog wordpress si trova nel seguente post Moving WordPress « WordPress Codex.

Di seguito l’esemplificazione, talvolta anche passo passo, delle operazioni da compiere per copiare un blog wordpress con base dati su server Linux Centos e web server IIS 7.5 su Windows 2008

1) Accedere alla cartella contenente l’applicazione WordPress da trasferire e copiarla nel nuovo server. A seconda delle connessioni da remoto supportate dal server sorgente si possono utilizzare una molteplicità di modalità di accesso per il trasferimento:  ftp, webdav, smb, vpn …

2) Sistemare i  permessi delle cartelle per l’esecuzione dell’applicazione da parte del web server IIS 7.5 locale. Lo user IIS_IUSR  deve avere gli appropriati permessi anche Users deve essere attenzionato.

WordPress in windows 2008 – permessi users




3)  Effettuata la copia delle cartelle si deve copiare il database.

Per ottenere le informazioni relative al database  visualizzare il file wp-config.php  si potranno visualizzare il nome del database, DB_NAME,  il nome del proprietario del database, DB_USER,  la password usata dal DB_USER,  DB_PASSWORD .

 
 * @package WordPress
 */

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'dbwp_name');

/** MySQL database username */
define('DB_USER', 'user_dbwp');

/** MySQL database password */
define('DB_PASSWORD', 'pass_user_dbwp');

/** MySQL hostname */
define('DB_HOST', 'hostname');

4) Effettuare il dump del database MySQL, del blog da trasferire, utilizzando i dati di accesso del file wp-config.php  con un comando dle tipo .

$ mysqldump -u user_dbwp --password=pass_user_dbwp -h host_wp_remoto dbwp_name > dbwp_name.sql

5) Caricare il dump del database nel nuovo server MySQL della macchina ubuntu locale:

Accedere al nuovo server Mysql con:

$ mysql -u root -h host -p

creare il nuovo database e lo user_dbwp con:

mysql> CREATE DATABASE dbwp_name;
mysql> GRANT ALL PRIVILEGES ON dbwp_name.* TO 'user_dbwp'@'localhost'
mysql> IDENTIFIED BY 'pass_user_dbwp' ;
mysql> FLUSH PRIVILEGES ;

caricare il database con :

$ mysql -u user_dbwp --password=pass_user_dbwp  -h host dbwp_name < dbwp_name.sql

6) Adesso è possbile avviare però i risultati saranno “stravaganti “e non sarà possbile navigare. Infatti si rende necessario sostituire almeno i nomi di dominio ed eventualmente gli urls.

Sostituzione del nome di dominio
In questo caso è necessario procedere alla ricerca dei vecchi valori,  sostituendoli con i nuovi. Per fare questo la soluzione ottimale consiste nell’utilizzare lo script scaricabile al seguente indirzzo Search and Replace for WordPress Databases Script. Lo script consente una sostituzioni sicura dei dati preservando l’integrità della lunghezza delle stringhe serializzate. Il codice funziona per qualsiasi piattaforma che memorizza array PHP serializzati in un database MySQL: Drupal Joomla. ATTENZIONE Lo script rappesenta un punto di vulnerabilità. Pertanto é bene usarlo rinominato e rimuoverlo dopo il suo utilizzo.

Possiamo anche scaricare e rendere disponibile lo script Download Search Replace DB v 2.1.0 con:

$ wget http://www.interconnectit.com/wp-content/uploads/2011/05/searchreplacedb21.zip
$ unzip searchreplacedb21.zip
$ cp    searchreplacedb21.php  /var/www/maurizio/_sr21.php 
$ chown www-data:www-data maurizio

Avviare  lo scripts facendo puntare il browser allo scipt stesso 192.168.66.162/maurizio/_sr2.php e seguire le indicazioni a video. Procedere con attenzione e cautela. Nel caso si compiano errori si può ricaricare il dump originale del database e ripetere l’operazione.

wordpress db search e replace
wordpress db search e replace start page

Sostituzione nome dominio maurizio.siagri.net con l’indirizzo locale 192.168.7.162/maurizio

wordpress db sostituzione nome dominio
wordpress db sostituzione nome dominio

Esito del search e replace nel database

wordpress db search and replace results
wordpress dbsearch and replace results

Adesso è possibile avviare il blog in locale http://192.168.7.162/maurizio

wp_blog_copiato

Risorse:

Annunci

Cambiare l’owner degli oggetti in un database postgresql: type, table, sequence, view, index,special, function

Una comoda query per modificare l’owner di tutti gli oggetti presenti in uno schema del database postreSQL.

La query è ripresa dal blog garysieling:  https://www.garysieling.com/blog/postgres-change-owner-all-objects-in-schema

Sono state apportate poche modifiche la principale per consentire l’utilizzo del maiuscolo nel nome degli oggetti e una diversa organizzazione degli oggetti type, table, sequence, index, view e special.

La query utilizza pg_class per visualizzare gli oggetti: tipo, tabella, sequenza, vista, indice e special.

Nel campo pg_class.relkind viene indicato il tipo di oggetto. Di seguito i codici presenti in relkind:

  • table ordinary = relkind = r
  • table TOAST  = t
  • table foreign = f
  • sequence = S
  • view = ‘v
  • index = ‘i
  • special = s
-- FUNCTION: public.__chown_object(character varying, character varying)

-- DROP FUNCTION public.__chown_object(character varying, character varying);

CREATE OR REPLACE FUNCTION public.__chown_object(
	in_schema character varying,
	new_owner character varying)
    RETURNS void
    LANGUAGE 'plpgsql'

    COST 100
    VOLATILE 
    --ROWS 0
AS $BODY$

DECLARE
  object_types VARCHAR[];
  object_classes VARCHAR[];
  object_type record;
 
  r record;
BEGIN
  -- modifica owner tipi, tabelle, sequenze, indici e viste
  object_types = '{type,table,table,sequence,index,view}';
  object_classes = '{c,t,r,S,i,v}';
 
  FOR object_type IN 
      SELECT unnest(object_types) type_name, 
                unnest(object_classes) code
  loop
    FOR r IN 
      EXECUTE '
          select n.nspname, c.relname 
          from pg_class c, pg_namespace n 
          where n.oid = c.relnamespace 
            and nspname = ''' || in_schema || '''
            and relkind = ''' || object_type.code || ''''
            
    loop 
      raise notice 'Changing ownership of % %.% to % %', 
                  object_type.type_name, 
                  r.nspname, r.relname, new_owner, object_type.code;
                     
             
     EXECUTE 
       'alter ' || object_type.type_name || ' '
                || r.nspname || '."' || r.relname 
                 || '" owner to ' || new_owner;
    END loop;
  END loop;
  -- end modifica owner tipi, tabelle, sequenze, indici e viste

  -- modifica owner funzioni 
  FOR r IN 
    SELECT  p.proname, n.nspname,
       pg_catalog.pg_get_function_identity_arguments(p.oid) args
    FROM    pg_catalog.pg_namespace n
    JOIN    pg_catalog.pg_proc p
    ON      p.pronamespace = n.oid
    WHERE   n.nspname = in_schema
  LOOP
    raise notice 'Changing ownership of function %.%(%) to %', 
                 r.nspname, r.proname, r.args, new_owner;
    EXECUTE 
       'alter function ' || r.nspname || '."' || r.proname ||
       '"(' || r.args || ') owner to ' || new_owner;
  END LOOP; 
  -- modifica owner funzioni 

  -- modifica owner particolari 
  FOR r IN 
    SELECT * 
    FROM pg_catalog.pg_namespace n
    JOIN pg_catalog.pg_ts_dict d 
      ON d.dictnamespace = n.oid
    WHERE n.nspname = in_schema
  LOOP
    EXECUTE 
       'alter text search dictionary ' || r.nspname || '.' || r.dictname || 
       ' owner to ' || new_owner;
  END LOOP;
  -- modifica owner particolari  -

END;

$BODY$;

ALTER FUNCTION public.__chown_object(character varying, character varying)
    OWNER TO postgresql;

Plpgsql 

Postgresql 

Postgresql cancella record duplicati

Creare eliminare database e tabelle

Formattare le tabelle con i CSS cellspacing e cellpadding – nuove classi per bootstrap

In Html 5.0 gli attributi delle tabelle cellspacing e cellpadding non sono attributi validi e devono essere sostituti con l’utilizzo dei CSS.

  • cellpadding definisce il padding di una cella della tabella: la distanza tra il contenuto della cella e il suo perimetro.
  • cellspacing  definisce la distanza tra le celle di una tabella.  

cellpadding

per replicare l’effetto di cellpadding si deve impostare il padding delle celle quindi:

table td {
    padding: 2px;
}

poichè una tabella  può avere un header e un footer meglio includere anche questi elementi nella definizione di stile

table th, table td, table tf {
     padding: 2px;
 }

cellspacing

in css la proprietà border-collapse consente di replicare cellspacing due i valori possibili separate e collapse.

per eleminare le distanze tra le celle

table {     
      border-collapse: collapse;
 }

Per inserire una distanza in pixel usare il valore separate e impostare la proprietà border-spacing

table {
      border-collapse: separate;
      border-spacing: 5px;
 }

Bootstrap e le tabelle

Bootstrap per le tabelle definisce alcune classi che consentono una buona formattazione delle tabelle  stesse

  • table-responsive
  • table-condensed
  • table-bordered
  • table-striped

Considerato che bootstrap per condensed utilizza un padding di 5px è preferibile invece che cambiare  il valore di padding definire una nuova classe da posizionare in un foglio di style accessorio con un padding più contenuto anche di soli 0px.

.table-xcondensed > thead > tr > th,
.table-xcondensed > tbody > tr > th,
.table-xcondensed > tfoot > tr > th,
.table-xcondensed > thead > tr > td,
.table-xcondensed > tbody > tr > td,
.table-xcondensed > tfoot > tr > td {
    padding: 2px!important;
}

Con riferimento alle tabelle usando bottstrap può far comodo disporre anche di una classe table-bordless per  eliminare completamente i bordi di una tabella

table.table-borderless td, table.table-borderless th {
    border: none!important;
}

.table-borderless > tbody > tr > td,
.table-borderless > tbody > tr > th,
.table-borderless > tfoot > tr > td,
.table-borderless > tfoot > tr > th,
.table-borderless > thead > tr > td,
.table-borderless > thead > tr > th {
    border: none!important;
}

 

 

Risorse:

 

 

 

IIRF per IIS 8.x Ionic’s – Isapi Rewrite filter

IIRF – Ionics Isapi Rewrite Filter – Home – è un efficente filtro ISAPI per il rewriting delle URL disponibile sia versione a 32 che a 64 bit.

Purtroppo l’ultima versione disponibile a 64 bit la 2.1.2.3-x64  non opera correttamente in IIS8.  Il problemi si manifestano per la parte che interessa il redirect mentre il rewrite si comporta adeguatamente.

Nelson Pires si è adoperato per rendere disponibile una versione libera di IIRF compatibile con IIS8. La versione del codice è stata curata da Pavel Surikov che ha aggiunto il supporto a IPv6.

La nuova versione è denominata IIRF-2.1.2.4-x64.

Un’altra possibilità per far girare IIRF su IIS8 consiste nell’utilizzare la versione IIRF-2.0.1.15 a 32 bit.
In questo è necessario impostare nell’Application pool
Enable 32-bit Application=true

 

Risorse:

 

asp.net RadioButtonList setting a default value

L’oggetto RadioButtonList

<asp:RadioButtonList ID="agree" Width="200px" RepeatDirection="horizontal" runat="server">
     <asp:ListItem Value="YES" Text="I agree" />
     <asp:ListItem Value="NO" Text="I do not agree" />
</asp:RadioButtonList>

come indicato nella figura sopra riportata non mostra un valore ( item) di  default selezionato.

Per selezionare un item di default si può utilizzare la proprietà Select impostandola a true

<asp:RadioButtonList ID="agree" Width="200px" RepeatDirection="horizontal" runat="server">
     <asp:ListItem Value="YES" Text="I agree" />
     <asp:ListItem Value="NO" Text="I do not agree" Select="true" />
</asp:RadioButtonList>

Oppure agire a livello di  back-end impostando la proprietà SelectedIndex. Il primo elemento ha valore 0 pertanto per seleziona la seconda voce ->

...
agree.SelectedIndex = 1;
...

Validazione dell’oggetto RadioButtonList

Per consenttire la sezione del solo valore (Value=) Yes corrispondente al  Text =” I agree” si può utilizzare nella proprietà ValidationExpression la regex =”^(?!NO)(.*)$”

ValidationExpression=”^(?!NO)(.*)$”

<asp:RadioButtonList ID="agree" Width="200px" RepeatDirection="horizontal" runat="server"&gt;
     <asp:ListItem Value="YES" Text="I agree" />
     <asp:ListItem Value="NO" Text="I do not agree" />
</asp:RadioButtonList>
<asp:RequiredFieldValidator ID="RequiredFieldValidator7" CssClass="label label-warning" Display="Dynamic" runat="server" ErrorMessage="Privacy. Checked Yes to Continue" ControlToValidate="agree" />
<asp:RegularExpressionValidator Visible="true" Display="Static" Enabled="true" CssClass="label label-warning" ID="RegularExpressionValidator6" ControlToValidate="agree" ValidationExpression="^(?!NO)(.*)$"
EnableClientScript="True" ErrorMessage="Privacy: Check YES to Continue!" runat="server" />

 

Convertire nel backend il valore testuale dell’oggetto RadioButtonLIst  in valore bool

bool myagree = agree.SelectedItem.Value == "YES" ? true : false;

 

Asp.net C# Null Reference Exception of RadioButtonList value

Quando si utilizza un controllo RadioButtonList si può ottenere il valore selezionato utilizzando:

RadioButtonList1.SelectedItem.Value;

Se tuttavia nessun elemento della RadioButtonList viene selezionato SelectedItem.Value risulta nullo e si ottiente l’errore:

Null Reference Exception of RadioButtonList value

Per evitare l’eccezione è sufficiente controllare preventivamente che SelectedItem non sia null.
In forma compatta:

string _radiobuttonvalue = RadioButtonList1.SelectedItem != null ? RadioButtonList1.SelectedItem.Value : "";

in forma tradizionale

if  ( RadioButtonList1.SelectedItem != null )  {  
   string _radiobuttonvalue = RadioButtonList1.SelectedItem.Value ; }

 

 

 

Risorse:

WordPress password dimenticata

wordpress.org Se si è dimenticata la password di amministratore di wordpress e il servizio di posta non è disponibile, per  recuperare l’accesso e l’installazione è possibile:

1) accedere al file wp-config.php
2) generare una nuova password inserendola direttamente nel database mysql.

1 ) accedere al file wp-config.php nella directory principale di wordpress. Il file wp-config contiene le informazioni di accesso al database grazie alle quali è possibile accedere alla tabella  _users con i dati e le password degli utenti

// ** MySQL settings - You can get this info from your web host ** //
 /** The name of the database for WordPress */
 define('DB_NAME', 'wpblog');
/** MySQL database username */
 define('DB_USER', 'wpdbadmin');
/** MySQL database password */
 define('DB_PASSWORD', 'miapassword');
/** MySQL hostname */
 # define('DB_HOST', 'localhost');
 define('DB_HOST', '192.168.1.100:3306');

WordPress passwords basate sul php password hashing.

Le password in word press sono memorizzate nella tabella xx_users

wp_passwd_adminer_1

2) Se si dispone dell’accesso al database mysql via phpMyAdmin o Adminer è possibile recuperare l’accesso a wordpress sostituendo la vecchia password ( dimenticata ) con una nuova password. Per la “crittografia” delle password wordpress utilizza il Portable PHP password hashing framework  ( le prime versioni utilizzavano invece MD5 ).

Il formato di una password che utilizza il php password hashing è facilmente distinguibile dal formato MD5.

php password hashing:   $P$BEMeAQICR602UR9RGRYtzzGz9SNKVA.
MD5 :  551583c11e1e3c9d8e6aeea9a84fe143

La classe con l’algoritmo per la gestione delle password è contenuta nel file ./wp-includes/class-phpass.php. Quindi per generare ad esempio la password di “MyPassword” è sufficiente disporre del file class-phpass.php e includerlo ad esempio nel file passwd_wp.php contenente uno script del tipo:

<!–?php

/** We want to hash password using the current DEFAULT algorithm. */
require(‘./class-phpass.php’);

/** Simple  instruction to generate password and/or to check password. */
$wp_hasher = new PasswordHash( 8, TRUE );
$password = ‘MyPassword‘;
$hashed_password = $wp_hasher->HashPassword( $password );

$checkpass = $wp_hasher->CheckPassword($password, $hashed_password) ;

echo “check result = “ . $checkpass ;
echo “\n”;
echo “password = “ . $password . “\n” ;
echo “hashed_password = “ . $hashed_password ;
echo “\n”;

?>

ll file può essere eseguito da terminale con

$ php passwd_wp.php

oppure può essere reso disponibile via webserver .

La password dimenticata può essere sostituita da una nuova password generata utilizzando lo script soprariportato e adminer o phpMyAdmin

wp_passwd_adminer_2

 

Risorse:

AjaxControlToolkit rilasciata la versione 15.1 l’atteso ajax lato server per Asp.net

ASP.net Ajax  Rilasciata l’attesa nuova versione dell’ AJAX Control Toolkit l’utile Ajax lato server per Asp.Net. L’ultima rilascio del dicembre 2013 lasciava un po’ a desiderare tant’è che  si avvertiva la necessità di un aggiornamento. Con la nuova versione la v15.1 c’è stato un significativo lavoro di revisione e miglioramento che evidenzia al primo impatto maggiore velocità e stabilità dei componenti.   Le novità della nuova versione che ha come nuovo mantainer DevExpress: What’s new.

Con la nuova versione termina il supporto alle versioni di Asp.Net precedenti la 4.0.

Unica nota dolente è disponibile, al momento,  solo la versione installabile che necessita della presenza di Visual Studio. Va considerato che ora  è disponibile una versione free di Visual Studio: la versione community.

Comunque una volta installata la versione del Control Toolkit, e creata la prima web application per aggiornare altre web application che fanno uso dell’Ajax  Control ToolKit sarà sufficiente :

  • prelevare i binari dalla cartella /bin e copiarli nella web application da aggiornare sostituendo quindi i files della precedente versione
  • apportare le modifiche base per l’utilizzo della nuova versione in particolare la sostituzione del controllo  <ajaxToolkit:ToolkitScriptManager …  con <asp:ScriptManager  ….
    Esemplificando

    <ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" />

    ora va sostituito con

    <asp:ScriptManager ID="ScriptManager2" runat="server" />


  • Eliminare se presenti dal web.config i riferimenti alla precedente versione del Control ToolKit
    come indicato in   Upgrade your project to AjaxControlToolkit v15.1 .
    Di fatto in web.config è sufficiente dichiarare il namespace AjaxControlToolkit

    <system.web>
    ......
       <pages>
           <controls>     
    ......
             <add namespace="AjaxControlToolkit" assembly="AjaxControlToolkit" tagPrefix="ajaxToolkit"/>
           </controls>
       </pages>
    </system.web>

 

Risorse: