在 Zend 中为 CMS 创建表单构建器


Creating a form builder for a CMS in Zend?

美好的一天,

我已经创建了一个显示页面CMS,但是我现在看到用户希望能够插入带有他们选择的字段的custom forms

我认为应该将form fields添加到链接到forms表的fields表中。诸如字段数据类型和验证以及是否应将信息存储在数据库中或将表单发送到的电子邮件地址之类的内容将被存储,然后用于在CMS的前端生成表单。

现在用于在页面中显示实际表单...用户如何设置字段在内容中的位置?我现在所拥有的只是一个text editor (ckeditor),用户可以在其中更改要显示的内容......他们如何告诉CMS在该特定页面中放置表单,CMS如何知道将表单添加到特定页面?

你有什么建议吗?

谢谢

简单的方法:
将所有不同的HTML节点拆分为基本的php对象,如单选按钮,复选框,选择,文件,文本区域和输入。为它们提供一些验证,例如输入整数。使用它们的内置表示形式将它们传递给表单构造类。

艰难的方式:
另一种方法是从逻辑上拆分提供的数据,以便列表、文本、文件和一个选项。文本可以有多个子类型,如整数、浮点数、日期电子邮件、您喜欢的内容(PHP 的正则表达式验证器在这里非常好(。此外,对于某些,您可以存储可用的选项或某些域,... .

对于其中一些类型,您有不同的选项可以在您的网站上呈现它们,即列表可以是多个输入元素,一个带有分隔符的文本区域或只是一个多选框。
因此,您可能希望从它们所表示的数据类型中独立化这些数据,这意味着您需要为这些基本数据类型(适配器(呈现HTML的类。

这些适配器将通过获取一个数据类型对象来构造,呈现由某个表单对象调用的 HTML,然后转换数据并将其发送到数据类型。然后,这些将验证它们并将它们存储在您的数据库中或其他任何内容中。

我认为最复杂的部分是将其与javascript验证放在一起,您可以为某些适配器和数据类型启用此功能。

正如@mjb4所说,您可以创建自己的表单类。该类可以添加新的表单元素,并且每个表单元素都是类中的一个对象。我自己也做过,非常方便。

.PHP

表单

本身保存在数据库中,可由表单类加载。它为每个表单元素启动相应的类。然后,您可以更改单个表单属性。您还可以添加新的表单元素或删除一些表单元素。

使用该方法$html = $form->getHTML();您可以获取html。它所做的只是简单地遍历所有表单元素对象并调用它们的getHTML方法。

发送表单时,您再次使用该类进行验证。它遍历所有表单元素并调用其 validateMe 方法。每个对象都知道表单元素具有哪个名称,并在$_REQUEST数组中查找它。

Jquery CMS 端

您可以使用 Jquery 创建表单创建者并将表单方案保存到数据库中。为用户提供两个保存表单数据的选项。一:通过电子邮件发送表单数据。二:创建新的数据库表并插入具有唯一 id 的数据。当提供选项二时,还应该有一个报告创建者,该创建者创建一个显示表单数据的页面(公共或私有(。

此外,您应该将html结构留给您php类。用户无需更改它。只需为他们创建一个女巫造型模板。

域对象

根据所需的灵活性,您将需要创建许多实体/域对象,这些对象将保存用户的自定义表单数据。

首先,表示表单元素的实体。我会创建FormFieldsetsFieldsFieldTypes。每个表单有 1 个或多个字段集,每个字段集有一个或多个字段等。

实际上正在 ZF2 中构建一个表单构建器,作为我公司当前的项目,我从一个可以扩展到所有表单"元素"的通用元素开始

/**
 * Base form element that all form elements extend
 */
abstract class Element implements ElementInterface, AttributeCollectionAwareInterface
{
  /**
   * @var string
   * @ODM'Id
   */
  protected $id;
  /**
   * @var string
   * @ODM'Field(type="string")
   */
  protected $name; 
  /**
   * @var string
   * @ODM'Field(type="string")
   */
  protected $label;
  /**
   * $attributes
   *
   * Map of form element attributes
   * 
   * @var array
   * @ODM'ReferenceMany(targetDocument="JobboardBase'Document'Form'Attribute")
   */
  protected $attributes;
  /**
   * $options
   *
   * Map of form element options
   * 
   * @var Doctrine'Common'Collections'Collection
   * @ODM'ReferenceMany(targetDocument="JobboardBase'Document'Form'Option")
   */
  protected $options;
  /**
   * @var status
   * 
   * @ODM'ReferenceOne(targetDocument="JobboardBase'Document'Form'Status")
   */
  protected $status;
  /**
   * $dateCreated
   *
   * The form creation date
   * 
   * @var 'MongoDate
   * @Gedmo'Timestampable(on="create")
   * @ODM'Field(type="date")
   */
  protected $dateCreated;
  /**
   * $dateUpdated
   *
   * The form updated date
   * 
   * @var 'MongoDate
   * @Gedmo'Timestampable(on="update")
   * @ODM'Field(type="date")
   */
  protected $dateUpdated;

这些实体应该具有尽可能接近Zend已经存在的Zend_Form_Element_*类(如$attributes$name$options等(的属性,这将在您需要在页面上呈现它们时为您提供帮助。

占位符

大多数CMS系统都有某种"占位符"功能 - "页面"被分解为几个"位置",如页眉,页脚,标题,内容等。同样,这些"位置"可以建模为可由用户编辑的实体,他们将能够将一个或多个"内容项"分配给"每个占位符,例如表单。

基本思想实际上是一种基于多个其他视图文件(有点像部分视图(组成页面视图的方法,其中的内容是根据配置动态生成的。

幸运的是,Zend 框架还提供了创建此类占位符的能力。他们的文件说:

视图占位符是为应用程序创建丰富布局的一种简单而强大的方法。您可以使用各种标准占位符,例如讨论的占位符(doctype((,headTitle((,headLink((和headScript(((,或使用通用占位符((帮助程序来聚合内容并以自定义方式呈现它。

模板化

占位符可以帮助您在设置区域中查找内容。但是,如果用户希望直接在文本内容(您的 ckeditor(中呈现表单,则此方法不起作用。

一种解决方案是为表单实现某种模板系统,其中设置的文本模板放置在内容中。

例如:

"这是我的联系我们 [表格][

id=123][姓名=联系我们][表格] 表格,请填写所有字段">

呈现表单时,请将此模板替换为实际表单 HTML。此方法可以很好地工作,前提是您在模板上具有创造性以确保没有误报,并且也许还有一些JS"添加表单"按钮来为用户创建模板文本。

一种可能的解决方案:

您的客户将创建的每个表单都有一个唯一的名称或 ID。

他们将使用 CMS 编辑页面的内容。 他们将在他们希望发件人出现的位置放置一个唯一的代码(商定的格式(。

前任。

##FORM_CONTINER_CONTACT_US##  // in this case the form is contact us based on ##FORM_CONTINER_XXXX## where XXX could be string or Id.

从数据库中提取页面内容后,将其传递给新功能

public function insertFormContiner($pageContetnt)
{
    // find the form container in $pageContent use regular expression to find it
    // get the unique name of the form container CONTACT_US in this case
    // build the form from the database (get the full html) 
    // replace the new created from with ##FORM_CONTINER_CONTACT_US## in this case
    // view the finale content of the page
    return $pageContent;
}

注意:您需要构建其他函数来处理提交时的表单。