Cómo cargar módulos de Jetpack sin activarlo

10 ago. 2016
·
  • What is code
  • WordPress
·
  • jetpack

En CampusPress nos dimos cuenta hace tiempo de que algunos módulos de Jetpack vienen muy bien para todos los usuarios pero no todos ellos van a activar el plugin al completo. Para no tener que sacar los módulos del código de Jetpack y utilizarlos como plugins individuales hemos dado con una fórmula para cargar sólo aquellos que nos interesan (los llamamos módulos obligatoriosmandatory en inglés) incluso si Jetpack está desactivado. El siguiente código es parecido al que utilizamos y lo que intenta es:

  • Carga el código base de Jetpack
  • Carga los módulos de Visibilidad de Widgets, Shortcodes Personalización de CSS  y los activa automáticamente.
  • Obvia el resto de los módulos. Jetpack no sabrá ni que existen.
  • Esconde Jetpack de la lista de plugins, por si alguien pretende activarlo
  • Desactiva Jetpack en caso de que estuviera activado.
  • Activa el modo developer en Jetpack
<?php

class Jetpack_Mandatory_Modules {

	public function __construct() {

		add_action( 'plugins_loaded', array( $this, 'load_base_jetpack' ) );

		// Este hook marcará los módulos obligatorios como activados
		// aquellos obligatorios que nosotros queremos
		add_filter( 'pre_option_jetpack_active_modules', array( $this, 'mandatory_modules' ), 500 );

		// Cargamos sólo los módulos obligatorios. Jetpack no tendrá en cuenta los demás
		add_filter( 'jetpack_get_available_modules', array( $this, 'mandatory_modules' ), 500 );

		// Ponemos Jetpack en modo Developer.
		add_filter( 'jetpack_development_mode', '__return_true' );

		// Y escondemos los menús de administración de Jetpack
		add_action( 'admin_init', array( $this, 'remove_jetpack_admin_menus' ), 500 );

		// Y que no aparezca Jetpack en la lista de plugins
		add_filter( 'all_plugins', array( $this, 'remove_jetpack_from_plugins_list' ) );

		// Como medida preventiva, desactivaremos Jetpack en caso de estar ya activado
		add_action( 'admin_init', array( $this, 'maybe_deactivate_jetpack' ) );
	}

	/**
	 * Quita Jetpack de la lista de plugins
	 *
	 * @param $plugins
	 *
	 * @return mixed
	 */
	public function remove_jetpack_from_plugins_list( $plugins ) {
		if ( isset( $plugins['jetpack/jetpack.php'] ) ) {
			unset( $plugins['jetpack/jetpack.php'] );
		}
		return $plugins;
	}

	/**
	 * Carga el código base de Jetpack
	 */
	public function load_base_jetpack() {
		$jetpack_dir = WP_CONTENT_DIR . '/plugins/jetpack';
		include_once( $jetpack_dir . '/jetpack.php' );
	}

	/**
	 * Módulos que siempre queremos tener cargados
	 *
	 * @return array
	 */
	public function mandatory_modules() {
		return array(
			'custom-css',
			'widget-visibility',
			'shortcodes'
		);
	}

	/**
	 * Carga los módulos obligatorios
	 */
	public function load_mandatory_modules() {
		$modules = self::mandatory_modules();
		foreach ( $modules as $module ) {
			if ( ! @include_once( Jetpack::get_module_path( $module ) ) ) {
				continue;
			}
		}
	}

	/**
	 * Elimina el menú de Jetpack del escritorio de WordPress
	 */
	public function remove_jetpack_admin_menus() {
		remove_menu_page( 'jetpack' );
		remove_submenu_page( 'jetpack', 'jetpack' );
		remove_submenu_page( 'jetpack', 'jetpack_modules' );
	}
	
	/**
	 * Desactiva Jetpack si ya está activado
	 */
	public function maybe_deactivate_jetpack() {
		$active_plugins = get_option( 'active_plugins' );
		if ( in_array( 'jetpack/jetpack.php', $active_plugins ) ) {
			deactivate_plugins( array( 'jetpack/jetpack.php' ), true );
		}
	}
}

// Instanciamos la clase en un hook temprano
// Ojo. las funciones anónimas no funcionan en PHP > 5.3
add_action( 'muplugins_loaded', function() {
	// Nueva instancia de nuestra clase
	new Jetpack_Mandatory_Modules();
});

El código tiene dos problemas:

  • Los módulos que requieran conexión a WordPress.com no funcionarían. En este caso no hace falta.
  • No permite activar Jetpack por lo que el usuario no tendrá control sobre ciertas cosas que podrían serle útiles

Este código funciona en instalaciones que tengamos muy controladas. Si el usuario pretende instalar Jetpack, no va a poder hacerlo.

Jetpack_Mandatory_Modules Redux

¿Se puede mejorar? ¡Claro!

La siguiente clase deja a los usuarios activar/desactivar Jetpack pero oculta los módulos que queremos siempre tener instalados para que no toquetee por ahí:

<?php

class Jetpack_Mandatory_Modules {

	public function __construct() {

		$active_plugins = get_option( 'active_plugins' );

		if ( ! in_array( 'jetpack/jetpack.php', $active_plugins ) ) {
			// Jetpack está desactivado pero lo vamos a cargar y ocultar

			// Cargamos el código base de Jetpack
			add_action( 'plugins_loaded', array( $this, 'load_base_jetpack' ) );

			// Este hook marcará los módulos obligatorios como activados
			// aquellos obligatorios que nosotros queremos
			add_filter( 'pre_option_jetpack_active_modules', array( $this, 'mandatory_modules' ), 500 );

			// Cargamos sólo los módulos obligatorios. Jetpack no tendrá en cuenta los demás
			add_filter( 'jetpack_get_available_modules', array( $this, 'mandatory_modules' ), 500 );

			// Ponemos Jetpack en modo Developer.
			add_filter( 'jetpack_development_mode', '__return_true' );

			// Y escondemos los menús de administración de Jetpack
			add_action( 'admin_init', array( $this, 'remove_jetpack_admin_menus' ), 500 );
		}
		else {
			// Jetpack está activado pero siempre queremos tener nuestros módulos obligatorios cargados
			
			// Carga los módulos obligatorios
			add_action( 'plugins_loaded', array( $this, 'load_mandatory_modules' ), 100 );

			// ...But remove them from the modules list, we don't need them
			add_filter( 'jetpack_get_available_modules', array( $this, 'remove_mandatory_modules_from_modules_list' ), 500 );
		}
	}

	/**
	 * Quita Jetpack de la lista de plugins
	 *
	 * @param $plugins
	 *
	 * @return mixed
	 */
	public function remove_jetpack_from_plugins_list( $plugins ) {
		if ( isset( $plugins['jetpack/jetpack.php'] ) ) {
			unset( $plugins['jetpack/jetpack.php'] );
		}
		return $plugins;
	}

	/**
	 * Carga el código base de Jetpack
	 */
	public function load_base_jetpack() {
		$jetpack_dir = WP_CONTENT_DIR . '/plugins/jetpack';
		include_once( $jetpack_dir . '/jetpack.php' );
	}

	/**
	 * Módulos que siempre queremos tener cargados
	 *
	 * @return array
	 */
	public function mandatory_modules() {
		return array(
			'custom-css',
			'widget-visibility',
			'shortcodes'
		);
	}

	/**
	 * Carga los módulos obligatorios
	 */
	public function load_mandatory_modules() {
		$modules = self::mandatory_modules();
		foreach ( $modules as $module ) {
			if ( ! @include_once( Jetpack::get_module_path( $module ) ) ) {
				continue;
			}
		}
	}

	/**
	 * Elimina el menú de Jetpack del escritorio de WordPress
	 */
	public function remove_jetpack_admin_menus() {
		remove_menu_page( 'jetpack' );
		remove_submenu_page( 'jetpack', 'jetpack' );
		remove_submenu_page( 'jetpack', 'jetpack_modules' );
	}

	/**
	 * Saca de la lista de módulos de Jetpack aquellos que son obligatorios
	 * para que el usuario no pueda verlos ni activarlos o desactivarlos
	 *
	 * @param array $modules
	 *
	 * @return array
	 */
	public function remove_mandatory_modules_from_modules_list( $modules ) {
		$default_modules = $this->mandatory_modules();
		$new_modules = array();
		foreach ( $modules as $module => $version ) {
			if ( in_array( $module, $default_modules ) ) {
				continue;
			}
			$new_modules[ $module ] = $version;
		}
		return $new_modules;
	}

}

// Instanciamos la clase en un hook temprano
// Ojo. las funciones anónimas no funcionan en PHP > 5.3
add_action( 'muplugins_loaded', function() {
	// Nueva instancia de nuestra clase
	new Jetpack_Mandatory_Modules();
});

Muy útil porque el usuario puede ahora activar y desactivar Jetpack, así como conectarse a cualquier servicio de WordPress.com pero los módulos obligatorios siempre estarán cargados.

Si siempre cargáis los mismos módulos de Jetpack para todos los clientes, este código puede ser de mucha ayuda para ahorrarnos algo de tiempo cuando creemos una nueva instalación.