Sunteți pe pagina 1din 41

Acerca de mí

Asier Marqués
One man army in Simettric.com

@asiermarques
github.com/Simettric
linkedin.com/in/asier
"Cuando miras al abismo,
el abismo también mira
dentro de tí"
WtfPress
WtfPress hell

— HTTP vs WP_Query
— Hooks oriented development
— Dependencias (plugins) delegadas en el
usuario
— Ausencia de aplicación de PSRs
— No se utiliza Composer
Wtf_Query

/category/animales => index.php?category=animales

WP_Query( array( “category” => “animales”) );

theme/category.php
Template hierarchy
WP_Query ruta personalizada

add_action('init', function() {

add_rewrite_rule( '^tasks/([^/]*)/?',
'index.php?post_type=task'
. '&category=$matches[1]'
. '&controller=mi_accion',
'top' );

add_rewrite_tag('%controller%', '(([^/]*))');

});
Al entrar en esa ruta...

$wp_query->query_vars["post_type"]

$wp_query->query_vars["category"]

$wp_query->query_vars["controller"]
...podemos llamar a nuestro "controlador"

add_action('parse_query', function(\WP_Query $wp_query)


{

if( $wp_query->query_vars["controller"] == "mi_accion" )


{
// ¿mi controlador?
}

});
Hooks driven
development
WordPress heaven

— Mercado
— Tendencia a utilizarse como prototipo
para validar mercado
— Su uso masivo
Cómo mejorarlo

— Composer
— Injección de dependencias
— Mejor gestión de rutas
— Eliminar lógica de negocio en templates
— MVC
— Sin romper compatibilidad
Demo
Aplicando MVC e
Inyección de dependencias
Inyección de dependencias

$container = new ContainerBuilder();

$loader = new YamlFileLoader($container,


new FileLocator([__DIR__ . "/Config"]));

$loader->load('services.yml');
Nuestro controller

class MiControlador {

/**
* Route("/custom-path/{method}", name="mi_ruta");
*/
function miAccion(Request $request)
{

return 'template.php';
}

}
Anotación de ruta

/**
* @Annotation
* @Target({"PROPERTY"})
*/
class Route{

/** @var string */


public $path;

/** @var string */


public $name;

function __construct( $data=[] ){

if (isset($data['value'])) {
$data['path'] = $data['value'];
unset($data['value']);
}

}
Recopilando las rutas

$routes = [];

AnnotationRegistry::registerFile( __DIR__ . "/Annotations/Route.php" );

$reflClass = new \ReflectionClass("MiControlador.php");

foreach($reflClass->getMethods() as $method) {

$classAnnotations = $reader->getMethodAnnotations($method);

foreach ($classAnnotations as $route) {

$routes[$route->name] = $route;

}
}
Ejecutar controlador

add_action('parse_query', function(\WP_Query $wp_query) use ($container)


{

if($route_name = $wp_query->query_vars[“route_name”])
{

if(isset( $routes[$route_name] ))
{

$route = $routes[$route_name];

$controller = $route->createControllerInstance( $container );

$template = call_user_function( [ $controller, $route->getAction() ] );

$container->get("view")->setTemplate($template);
}
}
});
Vistas

add_filter( 'template_include', function ( $template ) use ($container) {

return $container->get("view")->getTemplate() ? : $template;

}
¿Twig?
Una de las formas de hacerlo (ejemplo simplificado)

add_filter( 'template_include', function ( $template ) use ($container) {

if ( $template = $container->get("wp_query")->query_vars["twig.template"] ) {

$twig = $container->get("twig");

$twig->render( $template );

// gestionar el response y terminar ejecución

return $template;

}
sense.simettic.com
github.com/Simettric/Sense

Un proyecto en desarrollo activo, se acepta


feedback asier@simettric.com
Composer
Composer

— WPackagist.org
— Composer installers
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
}
],
"require": {
"php": ">=5.4",
"composer/installers": "1.*",
"johnpbloch/wordpress": "4.*",
"wpackagist-plugin/akismet": "dev-trunk",
"wpackagist-theme/hueman": "*"
},
"extra": {
"wordpress-install-dir": "public/_wordpress/",
"installer-paths": {
"public/wp-content/plugins/{$name}/": ["type:wordpress-plugin"],
"public/wp-content/themes/{$name}/": ["type:wordpress-theme"]
}
}
Estructura de directorios con Composer

Gestionados por composer

— public/_wordpress/
— public/wp-content/
— vendor/

Punto de entrada y configuración

— public/index.php
— public/wp-config.php
public/index.php

define('WP_USE_THEMES', true);

require( __DIR__ . '/_wordpress/wp-blog-header.php' );


public/wp-config.php

require __DIR__ . '/../vendor/autoload.php';

define( 'SITE_HOST', 'http://example.com' );


define( 'WP_SITEURL', SITE_HOST . '/_wordpress' );
define( 'WP_HOME', SITE_HOST . '/' );
define( 'WP_CONTENT_DIR', __DIR__ . '/wp-content' );
define( 'WP_CONTENT_URL', SITE_HOST . '/wp-content' );

if ( !defined('ABSPATH') )
define('ABSPATH', __DIR__ . '/_wordpress');
Demo
Una instalación base
github.com/Simettric/wordpress-composer-
installation
Entornos mixtos
WordPress + Symfony
EkinoWordpressBundle
Seguridad
Usando el login de WordPress para autenticarme en Symfony

ekino_wordpress:
security:
firewall_name: "secured_area"
login_url: "/wp-login.php"

security:
providers:
main:
entity: { class: Ekino\WordpressBundle\Entity\User, property: login }

firewalls:
secured_area:
pattern: ^/admin
access_denied_handler: ekino.wordpress.security.entry_point
entry_point: ekino.wordpress.security.entry_point
anonymous: ~

access_control:
- { path: ^/admin, roles: ROLE_WP_ADMINISTRATOR }
Repositorios

$postManager = $this->get('ekino.wordpress.manager.post');
$userManager = $this->get('ekino.wordpress.manager.user');

$user = $userManager->find(2);

$post = $postManager->find(1);
$post->setAuthor($user);

$postManager->save($post);
Conclusiones

— Se puede crear buen código en WordPress


sin estar acoplado
— Se puede iniciar un proyecto en
WordPress y migrar a Symfony después
— Se pueden integrar ambas plataformas
Code is poetry a symphony
Gracias
¿Preguntas?

Asier Marqués
One man army in Simettric.com

@asiermarques
github.com/Simettric
linkedin.com/in/asier

S-ar putea să vă placă și