evista / perform

反向表单API,可自动构建和处理表单 - 从标记。

0.1.3.1 2017-01-12 11:39 UTC

This package is auto-updated.

Last update: 2024-09-04 23:41:41 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

反向表单API,可自动构建和处理表单 - 从标记。

安装

通过Composer

$ composer require evista/perform

用法

$formService = new Service($crawler);
// Get form markup from the request to $formMarkup
$form = $formService->transpileForm($formMarkup);

Perform基于一个简单的概念:在模板或任何前端(如React.js)中用纯HTML构建你的表单,然后将它发送到服务器。后端将负责从你的标记构建一个表单对象 from your markup, populate 它从请求,并运行你的 validations

这使其区别于所有其他PHP表单API,因为不需要在服务器端在提交前构建任何表单对象。

以下是一个服务器端表单构建过程的示例

use Evista\Perform\Service;

// (...)

// Initialize form transpilation service (dependency injection friendly interface)
$formService = new Service($crawler);


$router->addRoute('POST', '/loginform', function (Request $request, Response $response) use($formService) {
    $formMarkup = $request->request->get('serform');
    $form = $formService->transpileForm($formMarkup);

    // Get fields:
    $fields = $form->getFields();

    // Get an input field named 'email'
    $emailField = $form->getField('email');

    // Get the field's submitted value
    $emailField->getValue();

    // Get attributes, eg. placeholder:
    $placeholder = $emailField->getAttribute('placeholder');

    // Get selected option:
    $selectField = $form->getField('test-select');
    $selected = $selectField->getValue();

    // Get the default selected option (that is selected in markup)
    $defaultSelected = $selectField->getDefaultSelectedOption();

    // Get files and handle them (multiple/single file upload)
    try {
        $fileField = $form->getField('files');
    } catch (FormFieldException $formFieldException) {
        $response = new Response();
        $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
        $response->setContent('Error: ' . $formFieldException->getMessage());
        $response->send();
        return $response;
    }
     
    $uploadedFiles = $fileField->getFiles();
    foreach ($uploadedFiles as $uploadedFile) {
        // Check real file type:
        $realType = $uploadedFile->getRealType(); // eg. image/png

        $userAddedName = $uploadedFile->getUserName;

        // Move the file to its final destination
        $uploadedFile->moveToDestination($destination = '/var/uploads/');

        // Get safe file name
        $safeBaseName = $uploadedFile->getSafeName(); // no extension

        // Get the original extension from filename
        $userExtension = $uploadedFile->getUserExtension();
    }

     // Check validity
    if (!$form->isValid()) {
        // All errors can be spotted in the fields
        foreach ($form->getFields() as $field) {
            if (!$field->isValid()) {
                $validationErrors[] = $field->getErrors();
            }
        }
        
        // Or a lot more conveniently:
        // This returns an array of Evista\Perform\ValueObject\ValidationError objects
        $allValidationErrors = $form->getValidationErrors();
    }

    // Then send some response
    $response = new JsonResponse(['dump'=>(var_export($form, true))]);
    return $response;
});

初始化表单构建器后,调用 transpileForm() 从标记构建表单对象。然后有一些有用的类方法来做任何你需要的事情,例如 getField($name) 获取任何字段的值。

$formMarkup = $request->request->get('serform');
$form = $formService->transpileForm($formMarkup);

标记与提交的数据一起到达,在 'serform' post参数中。例如,这个标记

<script src="/assets/bundle.js"></script>

<form method="post" action="/multiple-file-uploads" id="login-form">
    <p>
        <label for="email-1">Email: </label>
        <input type="email" name="email" placeholder="Your email" value="" pattern="^([a-zA-Z0-9_.+-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$" id="email-1">
    </p>
        <label for="passwd-1">Pass: </label>
        <input type="password" name="password" value="" id="passwd-1">
    </p>
    <p>
        <label for="desc-1">Longer description: </label>
    </p>
    <p>
        <textarea name="test_textarea" id="desc-1"></textarea>
    </p>
    <p>
        <select name="test-select">
            <option value="volvo">Volvo</option>
            <option value="saab" selected>Saab</option>
            <option value="mercedes">Mercedes</option>
            <option value="audi">Audi</option>
        </select>
    </p>
    <p>
        <input type="file" multiple name="files[]">
    </p>
    <p>
        <input type="submit" value="Submit" class="btn btn-primary">
    </p>
</form>

<script>
  (function() {
    var form = document.getElementById('login-form');
    form.onsubmit = function() {

      // Three params: DOM, success callback and error callback:
      Perform.submit(
        form,
        function success(result) {
          console.log('mysuccess', result);
          var response = JSON.parse(result.target.response);
          var dumper = document.getElementById('dumper');
          dumper.innerHTML = response.dump;
        },
        function error(error) {
          console.log('myError', error);
        }
      );

      return false;
    };
  })();
</script>

assets/bundle.js 中有一个javascript文件,通过POST将表单数据发送到表单的目标(action参数)通过一个名为Perform的全局对象。

在此repo中有该包的用法示例。

变更日志

有关最近更改的更多信息,请参阅CHANGELOG

测试

$ composer test

贡献

有关详细信息,请参阅CONTRIBUTINGCONDUCT

安全

如果您发现任何安全相关的问题,请通过电子邮件 balint.sera@gmail.com 而不是使用问题跟踪器。

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件