monster_menus-9.0.x-dev/src/Plugin/MMSearchAction/ExecutePHP.php
src/Plugin/MMSearchAction/ExecutePHP.php
<?php
namespace Drupal\monster_menus\Plugin\MMSearchAction;
use Drupal\Core\Form\EnforcedResponseException;
use Drupal\Core\Form\FormStateInterface;
use Drupal\monster_menus\Annotation\MMSearchAction;
use Drupal\monster_menus\MMSearchAction\MMSearchActionBase;
/**
* Provides the MM Search Results Action to execute arbitrary PHP code.
*
* @MMSearchAction(
* id = "mm_search_action_exec_php",
* label = @Translation("execute PHP code"),
* description = @Translation("Provides the MM Search Results Action to execute arbitrary PHP code."),
* )
*/
class ExecutePHP extends MMSearchActionBase {
final public const SESSION_DATA = 'mmsr-php';
/**
* @inheritDoc
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$default_php = $_SESSION[self::SESSION_DATA] ?? <<<'DEFAULT'
if ($nid) {
if ($node = \Drupal\node\entity\Node::load($nid)) {
}
}
if ($mmtid) {
}
DEFAULT;
$form['php'] = [
'#type' => 'textarea',
'#rows' => 10,
'#title' => $this->t('PHP code to execute'),
'#description' => $this->t('If the item is a node the variable <code>$nid</code> will contain its ID. If the item is an MM page or group the variable <code>$mmtid</code> will contain its ID. Anything printed or echoed will appear here afterward.'),
'#default_value' => $default_php,
];
$form['actions'] = [
'#type' => 'actions',
'#weight' => 1,
'result' => [
'#type' => 'submit',
'#value' => $this->t('Execute'),
'#attributes' => ['onclick' => 'MMSR_recalculate_action(jQuery("#edit-php").add(this)); return false;'],
],
];
$form['result'] = [
'#type' => 'details',
'#weight' => 2,
'#title' => $this->t('Results'),
'#open' => TRUE,
'#id' => 'actions-result',
'#attributes' => ['style' => 'display:none'],
];
return $form;
}
/**
* @inheritDoc
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$form_state->disableRedirect();
if ($php = $form_state->getValue('php')) {
$_SESSION[self::SESSION_DATA] = $php;
$result = $this->database->query($this->getConfiguration('result_query'));
ob_start();
try {
eval(<<<FUNC
\$func = function (\$nid, \$mmtid) {
$php
};
FUNC);
foreach ($result as $row) {
$nid = $mmtid = 0;
if (isset($row->nid)) {
$nid = $row->nid;
}
else {
$mmtid = $row->mmtid;
}
if (!empty($func)) {
$func($nid, $mmtid);
}
}
$printed = ob_get_contents();
}
catch (\Exception|\Throwable $e) {
$printed = ob_get_contents() . "\n" . $e->getMessage() . "\n" . $e->getTraceAsString();
}
ob_end_clean();
throw new EnforcedResponseException(mm_json_response([
'action_result' => '<code>' . str_replace("\n", '<br />', _filter_html_escape($printed)) . '</code>',
'action_result_div' => '#actions-result div',
]));
}
}
/**
* @inheritDoc
*/
public function applies() {
return $this->currentUser->hasPermission('execute php code');
}
/**
* @inheritDoc
*/
public function access() {
return TRUE;
}
}
