ID = $form_id;
$this->html = $html;
$this->meta = Alchemyst_Forms_Utils::clean_meta(get_post_meta($this->ID));
if (isset($this->meta['_alchemyst_forms-ga-submission-tracking'])) {
$this->track_ga = $this->meta['_alchemyst_forms-ga-submission-tracking'] == 1 ? 'true' : 'false';
if ($this->track_ga) {
$this->track_ga_event_name = $this->meta['_alchemyst_forms-ga-submission-tracking-event-name'];
}
}
}
/**
* A named method for getting a form, just a renamed prepare_for_output().
*/
public static function get_form($form_id) {
return self::prepare_for_output($form_id);
}
/**
*
*/
public static function get_all_forms() {
$args = array(
'post_type' => AF_POSTTYPE,
'posts_per_page' => -1,
'orderby' => 'post_title',
'order' => 'ASC'
);
return get_posts($args);
}
/**
* Render form validation for ajax forms
*/
public static function render_form_validation() {
?>
interpolate();
$html = self::modify_dom($html, $do_replacements, $post_id);
add_action('alchemyst_forms:before-form-output', array(__CLASS__, 'render_validation'), 10, 2);
add_action('alchemyst_forms:after-form-output', array(__CLASS__, 'hidden_inputs'), 10, 2);
add_action('alchemyst_forms:after-form-output', array(__CLASS__, 'render_preloader'), 10, 2);
return new Alchemyst_Form($post_id, $html);
}
public static function render_validation($form_id, $alchemyst_form) {
if (apply_filters('alchemyst_forms:render-form-validation', true, $form_id, $alchemyst_form)) : ?>
load($html);
// Any direct dom modifications should be completed by this point.
$html = $dom->root->innerHtml();
// TODO: Find root of this bug, this is a temporary fix.
$html = apply_filters('alchemyst-forms:modify-dom', $html, $form_id, $dom);
// TODO: Find root of this bug, this is a temporary fix.
$html = str_replace('\\LCURL\\', '{', $html);
$html = str_replace('\\RCURL\\', '}', $html);
$html .= '';
$html .= '';
$html .= '';
return $html;
}
public static function replace_repeatable_fields(&$dom) {
$repeatable_fields = $dom->find('repeatable');
foreach ($repeatable_fields as $repeatable) {
$node_id = $repeatable->id();
$required_count = $repeatable->getAttribute('data-required-count');
$maximum_count = $repeatable->getAttribute('data-maximum-count');
$add_label = $repeatable->getAttribute('data-add-label');
$minus_label = $repeatable->getAttribute('data-minus-label');
$tag = $repeatable->getTag();
$content = $repeatable->innerHtml();
$new_html = <<
{$content}
HTML;
$replace_minidom = new Dom;
$replace_minidom->load($new_html);
$repeater_arr = $replace_minidom->find('.alchemyst-forms-repeater-field');
$repeater = $repeater_arr[0];
if ($required_count)
$repeater->setAttribute('data-required-count', $required_count);
if ($maximum_count)
$repeater->setAttribute('data-maximum-count', $maximum_count);
if ($add_label)
$repeater->setAttribute('data-add-label', $add_label);
if ($minus_label)
$repeater->setAttribute('data-minus-label', $minus_label);
$repeater_fields = $replace_minidom->find('input, textarea, select');
foreach ($repeater_fields as $field) {
$name = $field->getAttribute('name');
if (!$name) continue;
$arr_pattern = "/\[\]/";
if (!preg_match($arr_pattern, $name))
$field->setAttribute('name', $name . '[]');
}
$repeatable->getParent()->replaceChild($node_id, $replace_minidom->root);
}
}
public static function replace_wysiwygs($html, $dom) {
$settings = array( 'media_buttons' => false, 'teeny' => true, 'quicktags' => false );
$settings = apply_filters('alchemyst_forms:wysiwyg-editor-settings', $settings);
$wysiwygs = $dom->find('input[type="wysiwyg"]');
foreach ($wysiwygs as $wysiwyg) {
if (!$wysiwyg->name) continue;
$tag = $wysiwyg;
$value = $wysiwyg->val ? $wysiwyg->val : '';
$id = $wysiwyg->name;
ob_start(); // Why wont wp editor just let us return the HTML...
wp_editor($value, $id, $settings);
$editor = ob_get_clean();
$html = str_replace($tag, $editor, $html);
}
return $html;
}
/**
* Gather required fields. Return an array of the field names (inputs, selects, textareas)
*
* @param $post_id - Contact form's post id to get required fields for.
* @param $dom - $dom object provided from Alchemyst_Form::get_dom() or equivelant.
*/
public static function get_required_fields($post_id, $dom) {
$fields = array();
$inputs = $dom->find('input');
foreach ($inputs as $input) {
if ($input->getAttribute('data-required') == "true")
$fields[] = $input->getAttribute('name');
}
$inputs = $dom->find('select');
foreach ($inputs as $input) {
if ($input->getAttribute('data-required') == "true")
$fields[] = $input->name;
}
$inputs = $dom->find('textarea');
foreach ($inputs as $input) {
if ($input->getAttribute('data-required') == "true")
$fields[] = $input->name;
}
return $fields;
}
/**
* Gather required fields. Return an array of the field names (inputs, selects, textareas)
*
* @param $post_id - Contact form's post id to get required fields for.
* @param $dom - $dom object provided from Alchemyst_Form::get_dom() or equivelant.
*/
public static function get_encrypted_fields($post_id, $dom) {
$fields = array();
$inputs = $dom->find('input');
foreach ($inputs as $input) {
if ($input->getAttribute('data-encrypted') == "true")
$fields[] = $input->name;
}
$inputs = $dom->find('select');
foreach ($inputs as $input) {
if ($input->getAttribute('data-encrypted') == "true")
$fields[] = $input->name;
}
$inputs = $dom->find('textarea');
foreach ($inputs as $input) {
if ($input->getAttribute('data-encrypted') == "true")
$fields[] = $input->name;
}
return $fields;
}
/**
* Return an array of matching fields (key matches value for field names)
*
* @param $post_id - Contact form's post id to get required fields for.
* @param $dom - $dom object provided from Alchemyst_Form::get_dom() or equivelant.
*/
public static function get_matching_fields($post_id, $dom) {
$fields = array();
$inputs = $dom->find('input');
foreach ($inputs as $input) {
$data_matches = $input->getAttribute('data-matches');
if (!empty($data_matches))
$fields[$input->name] = $input->getAttribute('data-matches');
}
$inputs = $dom->find('select');
foreach ($inputs as $input) {
$data_matches = $input->getAttribute('data-matches');
if (!empty($data_matches))
$fields[$input->name] = $input->getAttribute('data-matches');
}
$inputs = $dom->find('textarea');
foreach ($inputs as $input) {
$data_matches = $input->getAttribute('data-matches');
if (!empty($data_matches))
$fields[$input->name] = $input->getAttribute('data-matches');
}
return $fields;
}
/**
* Returns an array of minimum length fields (key = field name, value = (int) min-length)
*
* @param $post_id - Contact form's post id to get required fields for.
* @param $dom - $dom object provided from Alchemyst_Form::get_dom() or equivelant.
*/
public static function get_minimum_lengths($post_id, $dom) {
$fields = array();
$inputs = $dom->find('input');
foreach ($inputs as $input) {
$data_min_length = $input->getAttribute('data-min-length');
if (!empty($data_min_length))
$fields[$input->name] = (int) $input->getAttribute('data-min-length');
}
$inputs = $dom->find('select');
foreach ($inputs as $input) {
$data_min_length = $input->getAttribute('data-min-length');
if (!empty($data_min_length))
$fields[$input->name] = (int) $input->getAttribute('data-min-length');
}
$inputs = $dom->find('textarea');
foreach ($inputs as $input) {
$data_min_length = $input->getAttribute('data-min-length');
if (!empty($data_min_length))
$fields[$input->name] = (int) $input->getAttribute('data-min-length');
}
return $fields;
}
/**
* Returns an array of maximum length fields (key = field name, value = (int) max-length)
*
* @param $post_id - Contact form's post id to get required fields for.
* @param $dom - $dom object provided from Alchemyst_Form::get_dom() or equivelant.
*/
public static function get_maximum_lengths($post_id, $dom) {
$fields = array();
$inputs = $dom->find('input');
foreach ($inputs as $input) {
$data_max_length = $input->getAttribute('data-max-length');
if (!empty($data_max_length))
$fields[$input->name] = (int) $input->getAttribute('data-max-length');
}
$inputs = $dom->find('select');
foreach ($inputs as $input) {
$data_max_length = $input->getAttribute('data-max-length');
if (!empty($data_max_length))
$fields[$input->name] = (int) $input->getAttribute('data-max-length');
}
$inputs = $dom->find('textarea');
foreach ($inputs as $input) {
$data_max_length = $input->getAttribute('data-max-length');
if (!empty($data_max_length))
$fields[$input->name] = (int) $input->getAttribute('data-max-length');
}
return $fields;
}
/**
* Get a $dom object for a given form's post ID
*
* @param $form_id - Contact form's ID to get the $dom for.
*/
public static function get_dom($form_id) {
$form = self::prepare_for_output($form_id, false);
$dom = new Dom;
$dom->load($form->html);
return apply_filters('alchemyst_forms:get-dom', $dom, $form_id, $form);
}
/**
* Parse the dom for form values.
*/
public static function get_field_names($dom, $form_id) {
$names = $dom->find('[name]');
$field_names = array();
foreach ($names as $name) {
$n = $name->getAttribute('name');
if (strpos($n, '[') !== false) {
$n = substr($n, 0, strpos($n, '['));
}
// PHP replaces spaces with underscores, so we need to undo that.
$n = str_replace(' ', '_', $n);
$field_names[] = $n;
}
return apply_filters('alchemyst_forms:get-field-names', array_unique($field_names), $form_id, $dom);
}
/**
* If you want to get a form's field names by the form ID if you dont' already have a $dom available, use this.
*
* @param $form_id - Form's post ID to get field names for.
*/
public static function get_field_names_by_id($form_id) {
return self::get_field_names(self::get_dom($form_id), $form_id);
}
/**
* Entry view settings
*
* Get the entry view settings based on the current logged in user ID. This should never be called where nopriv
* is possible since it will fail.
*
* @param $form_id - Form post ID to get the view settinsg for.
*/
public static function get_entry_view_settings($form_id) {
$entry_settings = get_post_meta($form_id, '_alchemyst_forms-entry-view-settings-' . get_current_user_id(), true);
if ($entry_settings) {
return maybe_unserialize($entry_settings);
}
else {
$field_names = self::get_field_names_by_id($form_id);
$i = 0;
$visible_fields = array();
$field_order = array();
foreach ($field_names as $field_name) {
$field_order[] = $field_name;
if ($i < 8) {
$visible_fields[] = $field_name;
}
$i++;
}
return array(
'visible-fields' => $visible_fields,
'field-order' => $field_order
);
}
}
/**
* Simple post meta update to save entry view settings
*
* @param $form_id - Form's post ID to save the post meta for.
* @param $user_id - Current user's ID, but can be specified anyway.
* @param $visible_fields - Currently selected visible fields.
* @param $field_order - Ordered array of fields in the LTR order they should be displayed as.
*/
public static function save_entry_view_settings($form_id, $user_id, $visible_fields, $field_order) {
update_post_meta($form_id, '_alchemyst_forms-entry-view-settings-' . $user_id, array(
'visible-fields' => $visible_fields,
'field-order' => $field_order
));
}
/**
* Given a field name of an input[type="file"], return an array of settings that this upload must conform to.
* We cannot rely on client side stuff for this.
*
* References the default settings that are supplied in Alchemyst_Forms_Settings
*
* @param $field_name - Name of the input[type="file"] to get restrictions for.
* @param $dom - $dom provided from Alchemyst_Form::get_dom()
*/
public static function get_file_upload_restrictions($field_name, $dom) {
$file = $dom->find('input[name="' . $field_name . '"]');
if (!count($file)) return false;
$check_attributes = array(
'data-max-file-size' => $file->getAttribute('data-max-file-size'),
'data-allowed-types' => $file->getAttribute('data-allowed-types'),
'data-max-width' => $file->getAttribute('data-max-width'),
'data-max-height' => $file->getAttribute('data-max-height')
);
$max_size = $check_attributes['data-max-file-size'] ? $check_attributes['data-max-file-size'] : Alchemyst_Forms_Settings::get_setting('upload-max-file-size');
$allowed_types = array_map('trim', explode(',', ($check_attributes['data-allowed-types'] ? $check_attributes['data-allowed-types'] : Alchemyst_Forms_Settings::get_setting('upload-allowable-file-types'))));
$max_width = $check_attributes['data-max-width'] ? $check_attributes['data-max-width'] : Alchemyst_Forms_Settings::get_setting('upload-max-image-width');
$max_height = $check_attributes['data-max-height'] ? $check_attributes['data-max-height'] : Alchemyst_Forms_Settings::get_setting('upload-max-image-height');
if (empty($allowed_types) || !is_array($allowed_types)) {
return false;
}
elseif (!$max_size) {
return false;
}
if (in_array('jpg', $allowed_types) && !in_array('jpeg', $allowed_types)) $allowed_types[] = 'jpeg';
if (in_array('jpeg', $allowed_types) && !in_array('jpg', $allowed_types)) $allowed_types[] = 'jpg';
$image_types = array('jpg', 'jpeg', 'png', 'gif');
$is_image_only = true;
foreach ($allowed_types as $type) {
if (!in_array($type, $image_types)) $is_image_only = false;
}
return array(
'max-file-size' => $max_size,
'allowable-file-types' => $allowed_types,
'max-width' => $is_image_only ? $max_width : false,
'max-height' => $is_image_only ? $max_height : false
);
}
/**
* Get the field type for a given field_name.
* Useful for displaying entry rows differently depending on the type of field being used.
*
* Treats textareas, and selects as "text" inputs.
*
* @param $field_name - Name of the field to get the field type for.
* @param $dom - $dom provided from Alchemyst_Form::get_dom()
*/
public static function get_field_type($field_name, $dom) {
$input = $dom->find('[name="' . $field_name . '"]');
if (!count($input)) {
$input = $dom->find('[name="' . $field_name . '[]"]');
if (!count($input)) {
return false;
}
}
$tag_name = $input->getTag()->name();
$return_type = '';
if ($input->type) {
$return_type = $input->type;
}
else {
if ($tag_name == 'repeatable')
$return_type = 'repeatable';
else
$return_type = 'text';
}
return $return_type;
}
}