PageRenderTime 52ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/documentacion/extensions/SemanticForms/includes/SF_TemplateInForm.php

https://github.com/Skatox/mozilla-hispano.org
PHP | 208 lines | 159 code | 14 blank | 35 comment | 26 complexity | cc502c32765ca9a36fc1d19bae2f89c7 MD5 | raw file
Possible License(s): GPL-2.0, GPL-3.0
  1. <?php
  2. /**
  3. * Represents a template in a user-defined form.
  4. * @author Yaron Koren
  5. * @file
  6. * @ingroup SF
  7. */
  8. class SFTemplateInForm {
  9. private $mTemplateName;
  10. private $mLabel;
  11. private $mAllowMultiple;
  12. private $mMaxAllowed;
  13. private $mFields;
  14. /**
  15. * For a field name and its attached property name located in the
  16. * template text, create an SFTemplateField object out of it, and
  17. * add it to the $templateFields array.
  18. */
  19. function handlePropertySettingInTemplate( $fieldName, $propertyName, $isList, &$templateFields, $templateText ) {
  20. global $wgContLang;
  21. $templateField = SFTemplateField::create( $fieldName, $wgContLang->ucfirst( $fieldName ), $propertyName, $isList );
  22. $cur_pos = stripos( $templateText, $fieldName );
  23. $templateFields[$cur_pos] = $templateField;
  24. }
  25. /**
  26. * Get the fields of the template, along with the semantic property
  27. * attached to each one (if any), by parsing the text of the template.
  28. */
  29. function getAllFields() {
  30. global $wgContLang;
  31. $templateFields = array();
  32. $fieldNamesArray = array();
  33. // The way this works is that fields are found and then stored
  34. // in an array based on their location in the template text, so
  35. // that they can be returned in the order in which they appear
  36. // in the template, not the order in which they were found.
  37. // Some fields can be found more than once (especially if
  38. // they're part of an "#if" statement), so they're only
  39. // recorded the first time they're found.
  40. $template_title = Title::makeTitleSafe( NS_TEMPLATE, $this->mTemplateName );
  41. $template_article = null;
  42. if ( isset( $template_title ) ) $template_article = new Article( $template_title, 0 );
  43. if ( isset( $template_article ) ) {
  44. $templateText = $template_article->getContent();
  45. // Ignore 'noinclude' sections and 'includeonly' tags.
  46. $templateText = StringUtils::delimiterReplace( '<noinclude>', '</noinclude>', '', $templateText );
  47. $templateText = strtr( $templateText, array( '<includeonly>' => '', '</includeonly>' => '' ) );
  48. // First, look for "arraymap" parser function calls
  49. // that map a property onto a list.
  50. if ( $ret = preg_match_all( '/{{#arraymap:{{{([^|}]*:?[^|}]*)[^\[]*\[\[([^:]*:?[^:]*)::/mis', $templateText, $matches ) ) {
  51. foreach ( $matches[1] as $i => $field_name ) {
  52. if ( ! in_array( $field_name, $fieldNamesArray ) ) {
  53. $propertyName = $matches[2][$i];
  54. $this->handlePropertySettingInTemplate( $field_name, $propertyName, true, $templateFields, $templateText );
  55. $fieldNamesArray[] = $field_name;
  56. }
  57. }
  58. } elseif ( $ret === false ) {
  59. // There was an error in the preg_match_all()
  60. // call - let the user know about it.
  61. if ( preg_last_error() == PREG_BACKTRACK_LIMIT_ERROR ) {
  62. print 'Semantic Forms error: backtrace limit exceeded during parsing! Please increase the value of <a href="http://www.php.net/manual/en/pcre.configuration.php#ini.pcre.backtrack-limit">pcre.backtrack-limit</a> in the PHP settings.';
  63. }
  64. }
  65. // Second, look for normal property calls.
  66. if ( preg_match_all( '/\[\[([^:|\[\]]*:*?[^:|\[\]]*)::{{{([^\]\|}]*).*?\]\]/mis', $templateText, $matches ) ) {
  67. foreach ( $matches[1] as $i => $propertyName ) {
  68. $field_name = trim( $matches[2][$i] );
  69. if ( ! in_array( $field_name, $fieldNamesArray ) ) {
  70. $propertyName = trim( $propertyName );
  71. $this->handlePropertySettingInTemplate( $field_name, $propertyName, false, $templateFields, $templateText );
  72. $fieldNamesArray[] = $field_name;
  73. }
  74. }
  75. }
  76. // Then, get calls to #set and #set_internal
  77. // (thankfully, they have basically the same syntax).
  78. if ( preg_match_all( '/#(set|set_internal):(.*?}}})\s*}}/mis', $templateText, $matches ) ) {
  79. foreach ( $matches[2] as $match ) {
  80. if ( preg_match_all( '/([^|{]*?)=\s*{{{([^|}]*)/mis', $match, $matches2 ) ) {
  81. foreach ( $matches2[1] as $i => $propertyName ) {
  82. $fieldName = trim( $matches2[2][$i] );
  83. if ( ! in_array( $fieldName, $fieldNamesArray ) ) {
  84. $propertyName = trim( $propertyName );
  85. $this->handlePropertySettingInTemplate( $fieldName, $propertyName, false, $templateFields, $templateText );
  86. $fieldNamesArray[] = $fieldName;
  87. }
  88. }
  89. }
  90. }
  91. }
  92. // Then, get calls to #declare.
  93. if ( preg_match_all( '/#declare:(.*?)}}/mis', $templateText, $matches ) ) {
  94. foreach ( $matches[1] as $match ) {
  95. $setValues = explode( '|', $match );
  96. foreach ( $setValues as $valuePair ) {
  97. $keyAndVal = explode( '=', $valuePair );
  98. if ( count( $keyAndVal ) == 2 ) {
  99. $propertyName = trim( $keyAndVal[0] );
  100. $fieldName = trim( $keyAndVal[1] );
  101. if ( ! in_array( $fieldName, $fieldNamesArray ) ) {
  102. $this->handlePropertySettingInTemplate( $fieldName, $propertyName, false, $templateFields, $templateText );
  103. $fieldNamesArray[] = $fieldName;
  104. }
  105. }
  106. }
  107. }
  108. }
  109. // Finally, get any non-semantic fields defined.
  110. if ( preg_match_all( '/{{{([^|}]*)/mis', $templateText, $matches ) ) {
  111. foreach ( $matches[1] as $fieldName ) {
  112. $fieldName = trim( $fieldName );
  113. if ( !empty( $fieldName ) && ( ! in_array( $fieldName, $fieldNamesArray ) ) ) {
  114. $cur_pos = stripos( $templateText, $fieldName );
  115. $templateFields[$cur_pos] = SFTemplateField::create( $fieldName, $wgContLang->ucfirst( $fieldName ) );
  116. $fieldNamesArray[] = $fieldName;
  117. }
  118. }
  119. }
  120. }
  121. ksort( $templateFields );
  122. return $templateFields;
  123. }
  124. static function create( $name, $label = null, $allowMultiple = null, $maxAllowed = null, $formFields = null ) {
  125. $tif = new SFTemplateInForm();
  126. $tif->mTemplateName = str_replace( '_', ' ', $name );
  127. $tif->mFields = array();
  128. if ( is_null( $formFields ) ) {
  129. $fields = $tif->getAllFields();
  130. $field_num = 0;
  131. foreach ( $fields as $field ) {
  132. $tif->mFields[] = SFFormField::create( $field_num++, $field );
  133. }
  134. } else {
  135. $tif->mFields = $formFields;
  136. }
  137. $tif->mLabel = $label;
  138. $tif->mAllowMultiple = $allowMultiple;
  139. $tif->mMaxAllowed = $maxAllowed;
  140. return $tif;
  141. }
  142. function getTemplateName() {
  143. return $this->mTemplateName;
  144. }
  145. function getFields() {
  146. return $this->mFields;
  147. }
  148. function creationHTML( $template_num ) {
  149. $checked_str = ( $this->mAllowMultiple ) ? "checked" : "";
  150. $template_str = wfMsg( 'sf_createform_template' );
  151. $template_label_input = wfMsg( 'sf_createform_templatelabelinput' );
  152. $allow_multiple_text = wfMsg( 'sf_createform_allowmultiple' );
  153. $text = <<<END
  154. <input type="hidden" name="template_$template_num" value="$this->mTemplateName">
  155. <div class="templateForm">
  156. <h2>$template_str '$this->mTemplateName'</h2>
  157. <p>$template_label_input <input size=25 name="label_$template_num" value="$this->mLabel"></p>
  158. <p><input type="checkbox" name="allow_multiple_$template_num" $checked_str> $allow_multiple_text</p>
  159. <hr>
  160. END;
  161. foreach ( $this->mFields as $field ) {
  162. $text .= $field->creationHTML( $template_num );
  163. }
  164. $removeTemplateButton = Html::input(
  165. 'del_' . $template_num,
  166. wfMsg( 'sf_createform_removetemplate' ),
  167. 'submit'
  168. );
  169. $text .= "\t" . Html::rawElement( 'p', null, $removeTemplateButton ) . "\n";
  170. $text .= " </div>\n";
  171. return $text;
  172. }
  173. function createMarkup() {
  174. $text = "{{{for template|" . $this->mTemplateName;
  175. if ( $this->mAllowMultiple ) {
  176. $text .= "|multiple";
  177. }
  178. if ( $this->mLabel != '' ) {
  179. $text .= "|label=" . $this->mLabel;
  180. }
  181. $text .= "}}}\n";
  182. // For now, HTML for templates differs for multiple-instance
  183. // templates; this may change if handling of form definitions
  184. // gets more sophisticated.
  185. if ( ! $this->mAllowMultiple ) { $text .= "{| class=\"formtable\"\n"; }
  186. foreach ( $this->mFields as $i => $field ) {
  187. $is_last_field = ( $i == count( $this->mFields ) - 1 );
  188. $text .= $field->createMarkup( $this->mAllowMultiple, $is_last_field );
  189. }
  190. if ( ! $this->mAllowMultiple ) { $text .= "|}\n"; }
  191. $text .= "{{{end template}}}\n";
  192. return $text;
  193. }
  194. }