Continuando con la prueba de conexión entre el mundo de
Microsoft Access y
WordPress, llegamos al artículo número 6 en donde vamos ahora a realizar un ejemplo completo para unir lo que fuimos investigando en los 5 artículos anteriores de
XMLRPC, que recomiendo que leas antes de seguir:
¿En qué consistirá nuestro ejemplo completo?
Lo que buscamos al final del camino es haber creado en WordPress un post personalizado con campos personalizados y un archivo asociado.
Para ello desde MS Access, tendremos un formulario que nos pide tres datos y luego nos indica la URL del post creado, tal como se ve en la siguiente imagen:
En esta primera parte del código incorporamos la lógica, en donde primero subimos el archivo, y luego el post asociado a ese archivo:
Function CargarDocumentoConMetaDataEnWordPress( _
Cliente As String, Certificado As String, _
ArchivoConPath As String, Archivo As String) As String
Dim CodigoDocumento As String
Dim CodigoProceso As String
' Subo un archivo a la librería multimedia de WordPress y obtengo el código publicado
CodigoDocumento = PublicarMedioEnWordPress(Archivo, ArchivoConPath, "application/pdf")
If CodigoDocumento <> "-1" Then
' Subo cun ítem de custom post type, asociando el archivo subido
CodigoProceso = PublicarEnWordPress(CodigoDocumento, Certificado, Cliente)
If CodigoProceso <> "-1" Then
' URL en donde se cargó el post type
Else
MsgBox "Ocurrió un error al intentar subir un post type"
End If
Else
MsgBox "Ocurrió un error al intentar subir un documento"
End If
End Function
Código - Publicación de Imagen / Archivo
Hay algunos cambios resaltados respecto a artículos anteriores, que tienen que ver con el cambio de API a wp y con el análisis del XML devuelto como resultado.
Function PublicarMedioEnWordPress(ArchivoNombre As String, ArchivoConCamino As String, ArchivoTipo As String) As String
' Datos de Autenticación
CargarConstantes
txtURL = SITIO
txtUserName = USUARIO
txtPassword = PASSWORD
' Datos del Medio
txtArchivo = ArchivoNombre
txtTipo = ArchivoTipo
Dim txtArchivoConPath As String
txtArchivoConPath = ArchivoConCamino
' ServerXMLHTTP
Dim objSvrHTTP As ServerXMLHTTP
Dim strT As String
Set objSvrHTTP = New ServerXMLHTTP
' Autenticación
objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
objSvrHTTP.setRequestHeader "Accept", "application/xml"
objSvrHTTP.setRequestHeader "Content-Type", "application/xml"
strT = strT & "<methodCall>"
' Acción
strT = strT & "<methodName>wp.uploadFile</methodName>"
' General
strT = strT & "<params>"
strT = strT & "<param><value><string>0</string></value></param>"
strT = strT & "<param><value>" & txtUserName & "</value></param>"
strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
strT = strT & "<param>"
strT = strT & "<struct>"
' Nombre, Tipo e Imagen
strT = strT & "<member><name>name</name><value><![CDATA[" & txtArchivo & "]]></value></member>"
strT = strT & "<member><name>type</name><value><![CDATA[" & txtTipo & "]]></value></member>"
strT = strT & "<member><name>bits</name><value><base64>" & EncodeFile(txtArchivoConPath) & "</base64></value></member>"
strT = strT & "</struct>"
strT = strT & "</param>"
strT = strT & "</params>"
strT = strT & "</methodCall>"
' Publicación
objSvrHTTP.send strT
' Debug
Debug.Print objSvrHTTP.responseText
'MsgBox objSvrHTTP.responseText
PublicarMedioEnWordPress = resultado(objSvrHTTP.responseText, "MEDIA")
End Function
Public Function EncodeFile(strPicPath As String) As String
Const adTypeBinary = 1 ' Binary file is encoded
' Variables for encoding
Dim objXML
Dim objDocElem
' Variable for reading binary picture
Dim objStream
' Open data stream from picture
Set objStream = CreateObject("ADODB.Stream")
objStream.Type = adTypeBinary
objStream.Open
objStream.LoadFromFile (strPicPath)
' Create XML Document object and root node
' that will contain the data
Set objXML = CreateObject("MSXml2.DOMDocument")
Set objDocElem = objXML.createElement("Base64Data")
objDocElem.DataType = "bin.base64"
' Set binary value
objDocElem.nodeTypedValue = objStream.Read()
' Get base64 value
EncodeFile = objDocElem.Text
'EncodeFile = Replace(objDocElem.Text, vbLf, "")
' Clean all
Set objXML = Nothing
Set objDocElem = Nothing
Set objStream = Nothing
End Function
Código - Análisis de la respuesta
Esto es nuevo respecto a artículos anteriores y sirve para analizar el XML recibido como respuesta con el fin de encontrar el código interno que WordPress asignó a la imagen o post creado:
Function resultado(strXML, tipo As String) As String
Dim error As String
Dim hayError As Boolean
error = ""
hayError = False
Set xmlDoc = CreateObject("MSXML2.DOMDocument")
xmlDoc.loadXML strXML
' Busco errores
Set elements = xmlDoc.getElementsByTagName("fault")
For Each el In elements
error = error & el.Text
hayError = True
Next
' Si no hay errores
If Not hayError Then
' POST o MEDIA?
Dim tipoXML As String
If tipo = "POST" Then
tipoXML = "params"
Else
tipoXML = "string"
End If
Set elements = xmlDoc.getElementsByTagName(tipoXML)
' Obtengo el código generado
resultado = elements(0).Text
' Si hay errores
Else
MsgBox error
resultado = "-1"
End If
'MsgBox resultado
End Function
Código - Publicación de Custom Post Type
Y finalmente nuestra función para publicar el custom post type, con pocos cambios respecto a artículos anteriores:
Function PublicarEnWordPress(CodigoArchivo As String, NumeroDocumento As String, CodigoCliente As String) As String
' Datos de Autenticación
CargarConstantes
txtURL = SITIO
txtUserName = USUARIO
txtPassword = PASSWORD
' Datos del Post
txtTitulo = CodigoCliente & " - " & NumeroDocumento
txtContenido = "Este es un custom post de ejemplo publicado desde Microsoft Access"
Dim txtCategorias(1) As String
txtCategorias(1) = "Uncategorized"
'txtImagen = "64"
txtTipoContenido = "proceso"
txtCliente = CodigoCliente
txtNumeroCertificado = NumeroDocumento
txtDocumento = CodigoArchivo
' ServerXMLHTTP
Dim objSvrHTTP As ServerXMLHTTP
Dim strT As String
Set objSvrHTTP = New ServerXMLHTTP
' Autenticación
objSvrHTTP.Open "POST", txtURL, False, CStr(txtUsuario), CStr(txtPassword)
objSvrHTTP.setRequestHeader "Accept", "application/xml"
objSvrHTTP.setRequestHeader "Content-Type", "application/xml"
strT = strT & "<methodCall>"
' Acción
strT = strT & "<methodName>wp.newPost</methodName>"
' General
strT = strT & "<params>"
strT = strT & "<param><value><string>0</string></value></param>"
strT = strT & "<param><value>" & txtUserName & "</value></param>"
strT = strT & "<param><value><string>" & txtPassword & "</string></value></param>"
strT = strT & "<param>"
strT = strT & "<struct>"
' Categorías
strT = strT & "<member><name>categories</name><value><array>"
strT = strT & "<data>"
For i = 1 To UBound(txtCategorias)
strT = strT & "<value>" & txtCategorias(i) & "</value>"
Next i
strT = strT & "</data>"
strT = strT & "</array></value></member>"
' Título, contenido y fecha
strT = strT & "<member><name>post_content</name><value><![CDATA[" & txtContenido & "]]></value></member>"
strT = strT & "<member><name>post_title</name><value>" & txtTitulo & "</value></member>"
strT = strT & "<member><name>dateCreated</name><value><dateTime.iso8601>" & Format(Now(), "yyyyMMdd") & "T" & Format(Now(), "hh:mm:ss") & "</dateTime.iso8601></value></member>"
' Imagen destacada
' strT = strT & "<member><name>post_thumbnail</name><value><![CDATA[" & txtImagen & "]]></value></member>"
' Tipo de contenido
strT = strT & "<member><name>post_type</name><value>" & txtTipoContenido & "</value></member>"
' Campos personalizados
strT = strT & "<member><name>custom_fields</name><value><array><data><value>"
strT = strT & "<struct>"
strT = strT & "<member><name>key</name><value>cliente</value></member>"
strT = strT & "<member><name>value</name><value>" & txtCliente & "</value></member>"
strT = strT & "</struct>"
strT = strT & "<struct>"
strT = strT & "<member><name>key</name><value>numero_de_certificado</value></member>"
strT = strT & "<member><name>value</name><value>" & txtNumeroCertificado & "</value></member>"
strT = strT & "</struct>"
strT = strT & "<struct>"
strT = strT & "<member><name>key</name><value>documento</value></member>"
strT = strT & "<member><name>value</name><value>" & txtDocumento & "</value></member>"
strT = strT & "</struct>"
strT = strT & "</value></data></array></value></member>"
' Tipo de publicación
strT = strT & "<member><name>post_status</name><value>publish</value></member>"
strT = strT & "</struct>"
strT = strT & "</param>"
strT = strT & "</params>"
strT = strT & "</methodCall>"
' Publicación
objSvrHTTP.send strT
' Debug
Debug.Print objSvrHTTP.responseText
'MsgBox objSvrHTTP.responseText
PublicarEnWordPress = resultado(objSvrHTTP.responseText, "POST")
End Function
Cambios al sitio en WordPress
Un último detalle. Hemos creado un pequeño plugin en el sitio WordPress para que se puedan visualizar nuestros campos personalizados, tal como muestra la primera imagen de este post. Les dejo el código de ese plugin:
function retornar_ficha_proceso () {
if ( 'proceso' == get_post_type() ) {
$ficha = '
<table class="ficha_proceso">
<tr>
<td class="ficha_proceso_tit">CLIENTE:</td>
<td class="ficha_proceso_det">' . get_field('cliente') . '</td>
</tr>
<tr>
<td class="ficha_proceso_tit">NÚMERO DE CERTIFICADO:</td>
<td class="ficha_proceso_det">' . get_field('numero_de_certificado') . '</td>
</tr>
<tr>
<td class="ficha_proceso_tit">DOCUMENTO:</td>
<td class="ficha_proceso_det"><a href="' . wp_get_attachment_url(get_field('documento')) . '">' . get_the_title(get_field('documento')) . '</a></td>
</tr>
</table>
';
return $ficha;
}
}
function mostrar_proceso ($content) {
if ( 'proceso' == get_post_type() ) {
$content = retornar_ficha_proceso();
}
return $content;
}
add_filter('the_content', 'mostrar_proceso', 1);
Esos es todo por ahora, hasta la próxima!!!