'A & "B"', 'ids' => ['1', '2']]; $_POST = []; // @mago-ignore lint:no-request-variable -- Populate the legacy getFormData() input without processing an HTTP request. $_REQUEST = $_GET; $app = App::getInstance('html5-test'); $app->setParam(['character_set' => 'UTF-8', 'enable_session' => true, 'log_directory' => $include_root, 'log_file_priority' => false, 'log_screen_priority' => false]); $app->running = true; $app->carryQuery('query'); $app->carryQuery('ids'); $outputs = ['hidden' => $app->getHiddenSession(null, true)]; $document = new DOMDocument(); $document->loadHTML('Test
' . $outputs['hidden'] . '
'); $inputs = []; foreach ($document->getElementsByTagName('input') as $input) { $inputs[$input->getAttribute('name')][] = $input->getAttribute('value'); } html5Check(isset($inputs['query']) && $inputs['query'] === [$_GET['query']], 'Hidden fields retain escaped scalar values.'); html5Check(isset($inputs['ids[]']) && $inputs['ids[]'] === ['1', '2'], 'Hidden fields retain array names and values.'); html5Check(isset($inputs['csrf_token']) && $app->verifyCSRFToken($inputs['csrf_token'][0]), 'Hidden CSRF token remains valid.'); html5Check($app->getHiddenSession(false, false) === '', 'Disabling carried fields and CSRF emits no inputs.'); $fv = new FormValidator(); foreach ([MSG_ERR, MSG_WARNING, MSG_SUCCESS, MSG_NOTICE] as $type) { $app->raiseMsg('Message ' . $type, $type); $fv->addError('field-' . $type, 'Message ' . $type, $type); } ob_start(); $app->printRaisedMessages('Above', 'Below', true); $outputs['messages'] = ob_get_clean(); ob_start(); $fv->printErrorMessages('Above', 'Below', true); $outputs['validation'] = ob_get_clean(); foreach (['messages', 'validation'] as $name) { html5Check(substr_count($outputs[$name], 'aria-label="Dismiss alert"') === 4, "$name: all four message types retain dismissal controls."); html5Check(substr_count($outputs[$name], 'role="button"') === 4, "$name: dismissal controls have a role that permits an accessible name."); html5Check(strpos($outputs[$name], 'window.location.hash') !== false, "$name: scroll-to-message behavior remains available."); } html5Check($app->getRaisedMessages() === [], 'Rendering consumes raised messages.'); ob_start(); $app->printRaisedMessages(); html5Check(ob_get_clean() === '', 'An empty message queue emits no markup.'); $outputs['image'] = oImg('/missing-html5-fixture.png', 'A & "B"', 'width="10" height="20"'); $image = new Image(['base_path' => __DIR__, 'base_url' => '/images', 'default_image_file' => 'default.png']); $outputs['image-class'] = $image->oImg('missing-html5-fixture', 'A & "B"', 'width="10" height="20"'); $sort = new SortOrder('name', 'ASC'); $outputs['sort'] = $sort->asc_widget . $sort->desc_widget; ob_start(); HTML::printButtons([['name' => 'save_record', 'value' => 'Save & continue'], ['href' => '/cancel', 'value' => 'Cancel']]); $outputs['buttons'] = ob_get_clean(); ob_start(); printSubmitButtons(['legacy_save' => 'Save', ['name' => 'save_record', 'value' => 'Save & continue']]); $outputs['submit-buttons'] = ob_get_clean(); $paypal = new PayPal(true); $paypal->newButton('web_accept', 'fixture', ['business' => 'fixture@example.invalid', 'amount' => '12.34', 'item_name' => 'A & "B"']); ob_start(); $paypal->printButton('fixture'); $outputs['paypal'] = ob_get_clean(); html5Check(strpos($outputs['paypal'], 'www.sandbox.paypal.com') !== false, 'PayPal form keeps its configured destination.'); html5Check(strpos($outputs['paypal'], 'name="amount" value="12.34"') !== false, 'PayPal form preserves payment field names and values.'); foreach ($outputs as $name => $html) { html5Check(!preg_match('~<(?:input|img|br|hr|meta|link)\b[^>]*?/\s*>||\s(?:border|align|cellpadding|cellspacing)=|type="text/javascript"~', $html), "$name: emits HTML5 markup."); } // Include service templates and generators so newly scaffolded apps cannot reintroduce legacy syntax. $root = dirname(__DIR__); $files = 0; foreach (['lib', 'services', 'bin/module_maker', 'docs/examples', 'js'] as $directory) { foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($root . '/' . $directory, FilesystemIterator::SKIP_DOTS)) as $file) { if (!preg_match('/\.(php|ihtml|html|js)$/', $file)) { continue; } $files++; $source = file_get_contents($file); $legacy = '~<(?:input|img|br|hr|meta|link)\b[^\n]*?/\s*>||\s(?:border|align|valign|cellpadding|cellspacing|language)=["\']~i'; html5Check(!preg_match($legacy, $source), substr((string) $file, strlen($root) + 1) . ': contains legacy HTML output.'); } } foreach ($failures as $failure) { fwrite(STDERR, "FAIL: $failure\n"); } echo sprintf("HTML5: %d checks, %d source files, %d failures.\n", $checks, $files, count($failures)); exit($failures ? 1 : 0);