i+d=pumpún

Pumpún Dixital. Marqués de Valadares, 14, 5º Ofic 10. APP DEV. Desenvolvemos aplicacións para o ollo e o oído I+D+i PLUS.

Whatif PLugin + APP

Vimos de publicar un plugin para o xa framework WordPress co que abrimos conexión entre o theme Whatif (proxecto de Ecosistema Urbano) e un dispositivo Android (dende 1.6 ata 2.3.4 Gingerbread). Foi un parto longo, sobre todo porque o protocolo XML-RPC de WordPress ten limitacións importantes como a posibilidade de usar Custom Taxonomies ou os Custom Post Types. Tivemos que escribir código no plugin para habilitar estas novas funcións que forman parte do Framework Whatif.

A APP Android, que tamén foi programada no Estudo Pumpún, foi escrita seguindo o traballo da orixinal WordPress for Android e permite, entre outras…

“[…] introducir y etiquetar mensajes desde cualquier lugar, detectando automáticamente tu posición o dejándote elegirla, e incluyendo la posibilidad de adjuntar una fotografía en el mismo momento de publicar. También permite la consulta del contenido por ubicación, etiquetas, galería imágenes o lista de mensajes.”

Que é Whatif Móvil?

Como o seu propio nome indica, é a aplicación móbil de Whatif, concibida para consultar e publicar entradas desde calquera lugar, cunha interfaz secuencial similar pero adaptada á pantalla dun smartphone. Esta aplicación conéctase con calquera instalación da versión web de Whatif, sincronizando con esta os textos da interfaz e os contidos.

E o Plugin Whatif?

É o interface entre a máquina Android e o Framework Whatif. Son varias as funcións que incorpora e que foron necesarias para habilitar esta comunicación entre máquinas:

*Activa automaticamente o protocolo XML-RPC de publicacion remota en wordpress (por defecto ven desactivado).
*Ampla os métodos de entrada via protocolo XML-RPC (como a posibilidade de ler dinámicamente taxonomías especiáis).
*Permite a publicación de novos post que incorporan estas Custom Taxonomies.
*incorpora miniaturas na lista de post que se visualizan no panel de control de WordPress.
*Define as dimensións por defecto da miniatura saltándose a configuracioón por defecto de WordPress.

__

Detalles no código do Plugin

Por exemplo, esta función ben simple, activa o protocolo XML-RPC do WordPress si non estivera activado.

1
2
3
// AUTOMATICALLY TURNS THE XML-RPC PROTOCOL ON IN WORDPRESS
// ACTIVA AUTOMATICAMENTE EL PROTOCOLO XML-RPC DE PUBLICACION REMOTA EN WORDPRESS
update_option('enable_xmlrpc', '1');

Este outro cacho de código engade esa vista de miniaturas á lista de entradas no wordpress. Engade unha columna á dereita e dunha ollada permite coñecer cales post levan asociada unha imaxe (moi importante para o modo de visualización de imaxes da APP Android)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// ADD TUMBNAILS IN MANAGE POST/PAGES LIST
// INCORPORA MINIATURAS EN LA LISTA DE POST QUE SE VISUALIZA EN EL PANEL DE CONTROL DE WORDPRESS
 
if ( !function_exists('AddThumbColumn') && function_exists('add_theme_support') ) {
    // for post and page
    add_theme_support('post-thumbnails', array( 'post', 'page' ) );
    function AddThumbColumn($cols) {
        $cols['thumbnail'] = __('Thumbnail');
        return $cols;
    }
    function AddThumbValue($column_name, $post_id) {
            $width = (int) 60;
            $height = (int) 60;
            if ( 'thumbnail' == $column_name ) {
                // thumbnail of WP 2.9
                $thumbnail_id = get_post_meta( $post_id, '_thumbnail_id', true );
                // image from gallery
                $attachments = get_children( array('post_parent' => $post_id, 'post_type' => 'attachment', 'post_mime_type' => 'image') );
                if ($thumbnail_id)
                    $thumb = wp_get_attachment_image( $thumbnail_id, array($width, $height), true );
                elseif ($attachments) {
                    foreach ( $attachments as $attachment_id => $attachment ) {
                        $thumb = wp_get_attachment_image( $attachment_id, array($width, $height), true );
                    }
                }
                    if ( isset($thumb) && $thumb ) {
                        echo $thumb;
                    } else {
                        echo __('None');
                    }
            }
    }
    // for posts
    add_filter( 'manage_posts_columns', 'AddThumbColumn' );
    add_action( 'manage_posts_custom_column', 'AddThumbValue', 10, 2 );
    // for pages
    add_filter( 'manage_pages_columns', 'AddThumbColumn' );
    add_action( 'manage_pages_custom_column', 'AddThumbValue', 10, 2 );
}

E atención a estoutro que permite automatizar a Featured Image de cada artigo/post. Unha das formas de visualización de propostas/artigos da aplicación para Android é a través das imaxes que os usuarios toman da rúa con seus teléfonos. Cando o teléfono saca unha foto (ou adxunta unha da galería persoal), pégase ó artigo que está publicando e a imaxe envíase no momento da publicación. Pois ben, este cacho de código que se pode ver a continuación, permite que anque unha imaxe non se defina como Featured Image nun artigo/post de WordPress, a función colle a primeira imaxe do post e a define como Featured Image, o que permite navegar a través das imaxes e tamén visualizar a lista delas na propia lista de artigos no wordpress.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// CONVERTIR AUTOMATICAMENTE LA PRIMERA IMAGEN ASOCIADA A UN POST EN IMAGEN DESTACADA
if ( function_exists( 'add_theme_support' ) ) {
 
add_theme_support( 'post-thumbnails' );
 
      function easy_add_thumbnail() {
 
          global $post;
 
          $already_has_thumb = has_post_thumbnail();
 
              if (!$already_has_thumb)  {
 
              $attached_image = get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=image&numberposts=1" );
 
                          if ($attached_image) {
 
                                foreach ($attached_image as $attachment_id => $attachment) {                            	
                                add_post_meta($post->ID, '_thumbnail_id', $attachment_id, true);                                 
                                }     
 
                           }
 
                        }
      } // fin funcion
 
  add_action('the_post', 'easy_add_thumbnail');
 
  // hooks added to set the thumbnail when publishing too
  add_action('new_to_publish', 'easy_add_thumbnail');
  add_action('draft_to_publish', 'easy_add_thumbnail');
  add_action('pending_to_publish', 'easy_add_thumbnail');
  add_action('future_to_publish', 'easy_add_thumbnail');
 
} else {
 
    function eat_fail_requirements() {
 
      echo "<!-- Easy Add Thumbnail activated, but your WordPress doesn't support add_theme_support function -->";
 
    }
 
  add_action('wp_head', 'eat_fail_requirements');
 
}

E para rematar, aquí tedes o código completo do Plugin que incorpora un bo lote de funcións para ampliar as características do Protocolo XML-RPC. Unha morea de novas funcións que permiten incorporar os grandes pasos que deu o Framework WordPress neste último ano: a incorporación de tipos de post e a incorporación de taxonomías personalizadas que convirten, cando menos, un sistema de blog ordenado cronolóxicamente, nun potente CMS cuxos límites están na cabeza de quen traballa con eles.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
< ?php
/*
Plugin Name: WhatIf Android
Plugin URI: http://whatif.es/
Description: Enable connection between -What If Framework and Android APP-If.
Author: Pumpun Dixital
Version: 1.0
Author URI: http://pumpun.com
*/
 
/*  
This plugin is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2, as 
published by the Free Software Foundation.
 
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/
 
/*
 
 
88888888ba                                                                              88888888ba,    88               88                       88  
88      "8b                                                                             88      `"8b   ""               ""    ,d                 88  
88      ,8P                                                                             88        `8b                         88                 88  
88aaaaaa8P'  88       88  88,dPYba,,adPYba,   8b,dPPYba,   88       88  8b,dPPYba,      88         88  88  8b,     ,d8  88  MM88MMM  ,adPPYYba,  88  
88""""""'    88       88  88P'   "88"    "8a  88P'    "8a  88       88  88P'   `"8a     88         88  88   `Y8, ,8P'   88    88     ""     `Y8  88  
88           88       88  88      88      88  88       d8  88       88  88       88     88         8P  88     )888(     88    88     ,adPPPPP88  88  
88           "8a,   ,a88  88      88      88  88b,   ,a8"  "8a,   ,a88  88       88     88      .a8P   88   ,d8" "8b,   88    88,    88,    ,88  88  
88            `"YbbdP'Y8  88      88      88  88`YbbdP"'    `"YbbdP'Y8  88       88     88888888Y"'    88  8P'     `Y8  88    "Y888  `"8bbdP"Y8  88  
                                              88                                                                                                     
                                              88                                                                                                     
 
*/
 
 
// AUTOMATICALLY TURNS THE XML-RPC PROTOCOL ON IN WORDPRESS - ACTIVA AUTOMATICAMENTE EL PROTOCOLO XML-RPC DE PUBLICACION REMOTA EN WORDPRESS
 
update_option('enable_xmlrpc', '1');
 
 
// CUSTOM XMLRPC METHODS AMPLIA LOS METODOS DE ENTRADA VIA PROTOCOLO XML-RPC, EL SISTEMA DE PUBLICACION REMOTO DE WORDPRESS
 
add_filter( 'xmlrpc_methods', 'newMethods' );
 
function newMethods( $methods ) {
  $methods['wp.wifGetTaxonomies']       = 'wp_wifGetTaxonomies';
  $methods['wp.wifGetAllTaxonomies'] 	= 'wp_wifGetAllTaxonomies';
  $methods['wp.wifNewPost']      	 	= 'wp_wifNewPost';
  $methods['wp.wifGetRecentPosts']     	= 'wp_wifGetRecentPosts';
  $methods['wp.wifGetPage']     		= 'wp_wifGetPage';
  return $methods;
}
 
function wp_wifGetTaxonomies( $args ) {
 
	global $wp_xmlrpc_server;
 
	$wp_xmlrpc_server->escape($args);
 
	$blog_ID     = (int) $args[0]; // for future use
	$username  = $args[1];
	$password   = $args[2];
	$tipo		= $args[3];
 
	if ( !$wp_xmlrpc_server->login( $username, $password )  )
		return new IXR_Error( 401, $wp_xmlrpc_server->error->message );
 
	$tags = array( );
 
		if ( $all_tags = get_terms($tipo) ) {
			foreach( (array) $all_tags as $tag ) {
				$struct['tag_id']			= $tag->term_id;
				$struct['name']				= $tag->name;
				$struct['count']			= $tag->count;
				$struct['slug']				= $tag->slug;
 
				$tags[] = $struct;
			}
		}    
		return $tags;
}
 
function wp_wifGetAllTaxonomies( $args ) {
 
	global $wp_xmlrpc_server;
 
	$wp_xmlrpc_server->escape($args);
 
	$blog_ID     = (int) $args[0]; // for future use
	$username  = $args[1];
	$password   = $args[2];
 
	if ( !$wp_xmlrpc_server->login( $username, $password )  )
		return new IXR_Error( 401, $wp_xmlrpc_server->error->message );
 
	$tipo = "positivo";
	$tags = array( );
 
	if ( $all_tags = get_terms($tipo) ) {
		foreach( (array) $all_tags as $tag ) {
			$struct['tag_id']			= $tag->term_id;
			$struct['name']				= $tag->name;
			$struct['count']			= $tag->count;
			$struct['slug']				= $tag->slug;
			$struct['tipo']				= $tipo;
 
			$tags[] = $struct;
		}
	}    
 
	$tipo = "negativo";
	$tags_neg = array( );
 
	if ( $all_tags = get_terms($tipo) ) {
		foreach( (array) $all_tags as $tag ) {
			$struct_neg['tag_id']		= $tag->term_id;
			$struct_neg['name']			= $tag->name;
			$struct_neg['count']		= $tag->count;
			$struct_neg['slug']			= $tag->slug;
			$struct_neg['tipo']			= $tipo;
 
			$tags_neg[] = $struct_neg;
		}
	}    
	return array_merge($tags, $tags_neg);
}
 
// NEW POST WITH CUSTOM TAXONOMIES - PARA LA PUBLICACION DE NUEVOS POST CON CUSTOM TAXONOMIAS
 
function wp_wifNewPost($args) {
 
	global $wp_xmlrpc_server;
 
	$wp_xmlrpc_server->escape($args);
 
	$blog_ID     = (int) $args[0]; // we will support this in the near future
	$username  = $args[1];
	$password   = $args[2];
	$content_struct = $args[3];
	$publish     = isset( $args[4] ) ? $args[4] : 0;
 
	if ( !$user = $wp_xmlrpc_server->login($username, $password) )
		return $wp_xmlrpc_server->error;
 
	$page_template = '';
	if ( !empty( $content_struct['post_type'] ) ) {
		if ( $content_struct['post_type'] == 'page' ) {
			if ( $publish )
				$cap  = 'publish_pages';
			elseif ('publish' == $content_struct['page_status'])
				$cap  = 'publish_pages';
			else
				$cap = 'edit_pages';
			$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' );
			$post_type = 'page';
			if ( !empty( $content_struct['wp_page_template'] ) )
				$page_template = $content_struct['wp_page_template'];
		} elseif ( $content_struct['post_type'] == 'post' ) {
			if ( $publish )
				$cap  = 'publish_posts';
			elseif ('publish' == $content_struct['post_status'])
				$cap  = 'publish_posts';
			else
				$cap = 'edit_posts';
			$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
			$post_type = 'post';
		} else {
			// No other post_type values are allowed here
			return new IXR_Error( 401, __( 'Invalid post type.' ) );
		}
	} else {
		if ( $publish )
			$cap  = 'publish_posts';
		elseif ('publish' == $content_struct['post_status'])
			$cap  = 'publish_posts';
		else
			$cap = 'edit_posts';
		$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' );
		$post_type = 'post';
	}
 
	if ( !current_user_can( $cap ) )
		return new IXR_Error( 401, $error_message );
 
	// Check for a valid post format if one was given
	if ( isset( $content_struct['wp_post_format'] ) ) {
		$content_struct['wp_post_format'] = sanitize_key( $content_struct['wp_post_format'] );
		if ( !array_key_exists( $content_struct['wp_post_format'], get_post_format_strings() ) ) {
			return new IXR_Error( 404, __( 'Invalid post format' ) );
		}
	}
 
	// Let WordPress generate the post_name (slug) unless
	// one has been provided.
	$post_name = "";
	if ( isset($content_struct["wp_slug"]) )
		$post_name = $content_struct["wp_slug"];
 
	// Only use a password if one was given.
	if ( isset($content_struct["wp_password"]) )
		$post_password = $content_struct["wp_password"];
 
	// Only set a post parent if one was provided.
	if ( isset($content_struct["wp_page_parent_id"]) )
		$post_parent = $content_struct["wp_page_parent_id"];
 
	// Only set the menu_order if it was provided.
	if ( isset($content_struct["wp_page_order"]) )
		$menu_order = $content_struct["wp_page_order"];
 
	$post_author = $user->ID;
 
	// If an author id was provided then use it instead.
	if ( isset($content_struct["wp_author_id"]) && ($user->ID != $content_struct["wp_author_id"]) ) {
		switch ( $post_type ) {
			case "post":
				if ( !current_user_can("edit_others_posts") )
					return(new IXR_Error(401, __("You are not allowed to post as this user")));
				break;
			case "page":
				if ( !current_user_can("edit_others_pages") )
					return(new IXR_Error(401, __("You are not allowed to create pages as this user")));
				break;
			default:
				return(new IXR_Error(401, __("Invalid post type.")));
				break;
		}
		$post_author = $content_struct["wp_author_id"];
	}
 
	$post_title = isset( $content_struct['title'] ) ? $content_struct['title'] : null;
	$post_content = isset( $content_struct['description'] ) ? $content_struct['description'] : null;
 
	$post_status = $publish ? 'publish' : 'draft';
 
	if ( isset( $content_struct["{$post_type}_status"] ) ) {
		switch ( $content_struct["{$post_type}_status"] ) {
			case 'draft':
			case 'private':
			case 'publish':
				$post_status = $content_struct["{$post_type}_status"];
				break;
			case 'pending':
				// Pending is only valid for posts, not pages.
				if ( $post_type === 'post' )
					$post_status = $content_struct["{$post_type}_status"];
				break;
			default:
				$post_status = $publish ? 'publish' : 'draft';
				break;
		}
	}
 
	$post_excerpt = isset($content_struct['mt_excerpt']) ? $content_struct['mt_excerpt'] : null;
	$post_more = isset($content_struct['mt_text_more']) ? $content_struct['mt_text_more'] : null;
 
	$tags_input = isset($content_struct['mt_keywords']) ? $content_struct['mt_keywords'] : null;
	$taxonomytags_input = isset($content_struct['wp_taxonomytags']) ? $content_struct['wp_taxonomytags'] : null;
	$taxonomy_tipo = isset($content_struct['wp_taxonomy']) ? $content_struct['wp_taxonomy'] : null;
 
	if ( isset($content_struct["mt_allow_comments"]) ) {
		if ( !is_numeric($content_struct["mt_allow_comments"]) ) {
			switch ( $content_struct["mt_allow_comments"] ) {
				case "closed":
					$comment_status = "closed";
					break;
				case "open":
					$comment_status = "open";
					break;
				default:
					$comment_status = get_option("default_comment_status");
					break;
			}
		} else {
			switch ( (int) $content_struct["mt_allow_comments"] ) {
				case 0:
				case 2:
					$comment_status = "closed";
					break;
				case 1:
					$comment_status = "open";
					break;
				default:
					$comment_status = get_option("default_comment_status");
					break;
			}
		}
	} else {
		$comment_status = get_option("default_comment_status");
	}
 
	if ( isset($content_struct["mt_allow_pings"]) ) {
		if ( !is_numeric($content_struct["mt_allow_pings"]) ) {
			switch ( $content_struct['mt_allow_pings'] ) {
				case "closed":
					$ping_status = "closed";
					break;
				case "open":
					$ping_status = "open";
					break;
				default:
					$ping_status = get_option("default_ping_status");
					break;
			}
		} else {
			switch ( (int) $content_struct["mt_allow_pings"] ) {
				case 0:
					$ping_status = "closed";
					break;
				case 1:
					$ping_status = "open";
					break;
				default:
					$ping_status = get_option("default_ping_status");
					break;
			}
		}
	} else {
		$ping_status = get_option("default_ping_status");
	}
 
	if ( $post_more )
		$post_content = $post_content . "

This entry was written by chiu longina, posted on 9 Xullo, 2011 at 16:58, filed under Plugins and tagged , , . Leave a comment or view the discussion at the permalink.