Skip to content

Commit 4b18789

Browse files
committed
WpAjaxInitializer.
1 parent c04d77d commit 4b18789

File tree

13 files changed

+459
-2
lines changed

13 files changed

+459
-2
lines changed

DependencyInjection/WpSymfonyRouterExtension.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function load(array $configs, ContainerBuilder $container) : void
3838
);
3939

4040
$loader->load('services.yaml');
41+
$loader->load('native.yaml');
4142

4243
// Если не задействован FacadeBundle, то удалить фасады.
4344
if (!class_exists(AbstractFacade::class)) {
@@ -52,6 +53,8 @@ public function load(array $configs, ContainerBuilder $container) : void
5253
$container->setParameter('controller.annotations.path', []);
5354
}
5455

56+
$this->processNativeWpRoutes($container);
57+
5558
$this->registerRouterConfiguration(
5659
$config,
5760
$container
@@ -160,4 +163,31 @@ private function registerRouterConfiguration(
160163
]);
161164
}
162165
}
166+
167+
/**
168+
* Обработка "нативных" роутов (wp-admin/admin_ajax.php).
169+
*
170+
* @param ContainerBuilder $container
171+
*
172+
* @return void
173+
*
174+
* @since 13.06.2021
175+
*/
176+
private function processNativeWpRoutes(ContainerBuilder $container): void
177+
{
178+
// Путь к "нативным" роутам WP.
179+
if (!$container->hasParameter('yaml.native.routes.file')) {
180+
$container->setParameter('yaml.native.routes.file', '/app/wp_routes.yaml');
181+
}
182+
183+
$nativeRoutesPath = $container->getParameter('yaml.native.routes.file');
184+
$root = $container->getParameter('kernel.project_dir');
185+
186+
// Если файл с роутами не существует, то выпилить из контейнера
187+
// соответствующие сервисы.
188+
if (!file_exists($root . $nativeRoutesPath)) {
189+
$container->removeDefinition('wp_ajax.loader');
190+
$container->removeDefinition('wp_ajax.initializer');
191+
}
192+
}
163193
}

Resources/config/native.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
##########
2+
# Роутер
3+
##########
4+
5+
services:
6+
# конфигурация по умолчанию в *этом* файле
7+
_defaults:
8+
autowire: true
9+
autoconfigure: true
10+
public: true
11+
12+
wp_ajax.loader:
13+
public: false
14+
class: Symfony\Component\Routing\RouteCollection
15+
factory: ['@routing.loader', 'load']
16+
arguments: ['%kernel.project_dir%/%yaml.native.routes.file%']
17+
18+
wp_ajax.initializer:
19+
class: Prokl\WpSymfonyRouterBundle\Services\NativeAjax\WpAjaxInitializer
20+
arguments: ['@wp_ajax.loader', '@service_container']
21+
tags: ['service.bootstrap']
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Prokl\WpSymfonyRouterBundle\Services\NativeAjax;
4+
5+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
6+
use Symfony\Component\HttpFoundation\Request;
7+
8+
/**
9+
* Class AbstractWPAjaxController
10+
* @package Prokl\WpSymfonyRouterBundle\Services\NativeAjax
11+
*/
12+
class AbstractWPAjaxController extends AbstractController
13+
{
14+
/**
15+
* @var Request $request
16+
*/
17+
protected $request;
18+
19+
/**
20+
* AbstractWPAjaxController constructor.
21+
*
22+
* @param Request|null $request
23+
*/
24+
public function __construct(?Request $request = null)
25+
{
26+
$this->request = $request;
27+
if ($request === null) {
28+
$this->request = Request::createFromGlobals();
29+
}
30+
}
31+
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
<?php
2+
3+
namespace Prokl\WpSymfonyRouterBundle\Services\NativeAjax;
4+
5+
use ReflectionException;
6+
use ReflectionMethod;
7+
use RuntimeException;
8+
use Symfony\Component\DependencyInjection\ContainerInterface;
9+
use Symfony\Component\Routing\RouteCollection;
10+
11+
/**
12+
* Class Prokl\WpSymfonyRouterBundle\Services\NativeAjax
13+
* @package Fedy\Services\Wordpress
14+
*
15+
* @since 12.06.2021
16+
*/
17+
class WpAjaxInitializer
18+
{
19+
/**
20+
* @var RouteCollection $routes Роуты.
21+
*/
22+
private $routes;
23+
24+
/**
25+
* @var ContainerInterface $container Контейнер.
26+
*/
27+
private $container;
28+
29+
/**
30+
* WpAjaxInitializer constructor.
31+
*
32+
* @param RouteCollection $routes Роуты.
33+
* @param ContainerInterface $container Контейнер.
34+
*/
35+
public function __construct(RouteCollection $routes, ContainerInterface $container)
36+
{
37+
$this->routes = $routes;
38+
$this->container = $container;
39+
40+
$this->init();
41+
}
42+
43+
/**
44+
* Инициализация.
45+
*
46+
* @return void
47+
*/
48+
private function init() : void
49+
{
50+
$routes = $this->routes->all();
51+
foreach ($routes as $action => $route) {
52+
$defaults = $route->getDefaults();
53+
// Публичный роут или нет
54+
$public = $defaults['_public'];
55+
56+
$controller = $this->parseController($defaults['_controller']);
57+
58+
add_action("wp_ajax_{$action}", $controller);
59+
if ($public) {
60+
add_action("wp_ajax_nopriv_{$action}", $controller);
61+
}
62+
}
63+
}
64+
65+
/**
66+
* @param array|string|object $controller
67+
*
68+
* @return array|false|object|string|string[]|null
69+
* @throws RuntimeException Когда не получилось распарсить контроллер.
70+
*/
71+
private function parseController($controller)
72+
{
73+
if (is_string($controller)) {
74+
if (strpos($controller, '::') !== false) {
75+
$controller = explode('::', $controller, 2);
76+
} else {
77+
// Invoked controller.
78+
try {
79+
new ReflectionMethod($controller, '__invoke');
80+
$controller = [$controller, '__invoke'];
81+
} catch (ReflectionException $e) {
82+
return [];
83+
}
84+
}
85+
}
86+
87+
if (is_array($controller)) {
88+
if (is_string($controller[0]) && !$this->container->has($controller[0])) {
89+
throw new RuntimeException(
90+
sprintf(
91+
'Controller %s not found in container. Forgot mark him as service?',
92+
$controller[0]
93+
),
94+
);
95+
}
96+
97+
$controller[0] = $this->container->get($controller[0]);
98+
99+
return $controller;
100+
}
101+
102+
if (is_object($controller)) {
103+
return [$controller];
104+
}
105+
106+
throw new RuntimeException(
107+
'Error parsing controller'
108+
);
109+
}
110+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<?php
2+
3+
namespace Prokl\WpSymfonyRouterBundle\Tests\Cases;
4+
5+
use Prokl\WordpressCi\Base\WordpressableAjaxTestCase;
6+
7+
/**
8+
* Class SampleAjaxControllerTest
9+
* @package Fedy\Services\Wordpress
10+
*/
11+
class SampleAjaxControllerTest extends WordpressableAjaxTestCase
12+
{
13+
protected function setUp() : void
14+
{
15+
parent::setup();
16+
wp_set_current_user( 1 );
17+
}
18+
19+
public function testAction() : void
20+
{
21+
$this->_handleAjax('examples_wp');
22+
$result = $this->_last_response;
23+
$this->assertSame('OK', $result);
24+
}
25+
}

0 commit comments

Comments
 (0)