private static function register_pending_item_types() { if (!is_array(self::$item_types_pending_registration)) { // all pending item types already registered return; } foreach (self::$item_types_pending_registration as $item_type_class) { if (is_string($item_type_class)) { $item_type_instance = new $item_type_class(); } else { $item_type_instance = $item_type_class; } unset($item_type_class); if (!is_subclass_of($item_type_instance, 'FW_Option_Type_Builder_Item')) { trigger_error('Invalid builder item type class ' . get_class($item_type_instance), E_USER_WARNING); continue; } $builder_type = $item_type_instance->get_builder_type(); /** * @var FW_Option_Type_Builder $builder_type_instance */ $builder_type_instance = fw()->backend->option_type($builder_type); if (!$builder_type_instance->item_type_is_valid($item_type_instance)) { trigger_error('Invalid builder item. (type: ' . $item_type_instance->get_type() . ')', E_USER_WARNING); continue; } $builder_type_instance->_register_item_type($item_type_instance); } self::$item_types_pending_registration = false; }
/** * @internal * {@inheritdoc} */ protected function _render($id, $option, $data) { $static_uri = fw()->extensions->get('page-builder')->get_uri('/includes/page-builder/static'); $version = fw()->extensions->get('page-builder')->manifest->get_version(); wp_enqueue_style('fw-option-type-' . $this->get_type(), $static_uri . '/css/styles.css', array(), $version); /* * there should not be (and it does not make sens to be) * more than one page builder per page that is integrated * with the default post content editor * integration in the sens of inserting the button to activate/deactivate * the builder, to replace the post content with the shortcode notation */ if ($this->editor_integration_enabled && $option['editor_integration'] === true) { trigger_error(__('There must not be more than one page Editor integrated with the wp post editor per page', 'fw'), E_USER_ERROR); } elseif ($option['editor_integration'] === true) { $this->editor_integration_enabled = true; wp_enqueue_style('fw-option-type-' . $this->get_type() . '-editor-integration', $static_uri . '/css/editor_integration.css', array(), $version); wp_enqueue_script('fw-option-type-' . $this->get_type() . '-editor-integration', $static_uri . '/js/editor_integration.js', array('jquery', 'fw-events'), $version, true); $builder_templates = apply_filters('fw_ext_page_builder_templates', array()); // remove not existing templates $builder_templates = array_intersect(array_keys(wp_get_theme()->get_page_templates()), $builder_templates); /** * Make sure the array is not associative array('template.php', ...) * instead of array(2 => 'template.php', ...) * because the json needs to be ['template.php', ...] instead of {2: 'template.php', ...} */ $builder_templates = array_values($builder_templates); wp_localize_script('fw-option-type-' . $this->get_type() . '-editor-integration', 'fw_option_type_' . str_replace('-', '_', $this->get_type()) . '_editor_integration_data', array('l10n' => array('showButton' => __('Visual Page Builder', 'fw'), 'hideButton' => __('Default Editor', 'fw')), 'optionId' => $option['attr']['id'], 'renderInBuilderMode' => isset($data['value']['builder_active']) ? $data['value']['builder_active'] : apply_filters('fw_page_builder_set_as_default', false), 'builderTemplates' => $builder_templates)); } return parent::_render($id, $option, $data); }
private static function get_access_key() { if (!self::$access_key) { self::$access_key = new FW_Access_Key('fw_ext_builder_option_type'); } return self::$access_key; }
/** * @internal */ protected function _get_value_from_input($option, $input_value) { $value = parent::_get_value_from_input($option, $input_value); $value['shortcode_notation'] = $this->get_shortcode_notation(json_decode($value['json'], true)); if ($option['editor_integration'] === true) { $value['builder_active'] = isset($_POST['layout-builder-active']) && $_POST['layout-builder-active'] === 'true'; } return $value; }
} /** * {@inheritdoc} */ public function get_value_from_attributes($attributes) { return $this->get_fixed_attributes($attributes); } /** * {@inheritdoc} */ public function frontend_render(array $item, $input_value) { return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('title' => $item['options']['title'], 'subtitle' => $item['options']['subtitle'])); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { } /** * {@inheritdoc} */ public function visual_only() { return true; } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Form_Header_Title');
$attr['checked'] = 'checked'; } $choices[] = $attr; } if ($options['randomize']) { shuffle($choices); } return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'choices' => $choices, 'value' => $value)); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $options = $item['options']; $messages = array('required' => str_replace(array('{label}'), array($options['label']), __('The {label} field is required', 'fw')), 'not_existing_choices' => str_replace(array('{label}'), array($options['label']), __('{label}: Submitted data contains not existing choices', 'fw'))); if (empty($options['choices'])) { // the item was not displayed in frontend return; } if ($options['required'] && empty($input_value)) { return $messages['required']; } // check if has not existing choices if (!empty($input_value) && count($input_value) != count(array_intersect($options['choices'], $input_value))) { return $messages['not_existing_choices']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Checkboxes');
*/ $attributes['atts'] = fw_get_options_values_from_input($shortcode_data['options'], array()); } else { /** * There are saved attributes. * But we need to execute the _get_value_from_input() method for all options, * because some of them may be (need to be) changed (auto-generated) https://github.com/ThemeFuse/Unyson/issues/275 * Add the values to $option['value'] */ $options = fw_extract_only_options($shortcode_data['options']); foreach ($attributes['atts'] as $option_id => $option_value) { if (isset($options[$option_id])) { $options[$option_id]['value'] = $option_value; } } $attributes['atts'] = fw_get_options_values_from_input($options, array()); } } return $attributes; } public function get_shortcode_data($atts = array()) { $return = array('tag' => $atts['shortcode']); if (isset($atts['atts'])) { $return['atts'] = $atts['atts']; } return $return; } } FW_Option_Type_Builder::register_item_type('Page_Builder_Simple_Item');
* There are saved attributes. * But we need to execute the _get_value_from_input() method for all options, * because some of them may be (need to be) changed (auto-generated) https://github.com/ThemeFuse/Unyson/issues/275 * Add the values to $option['value'] */ $options = fw_extract_only_options($options); foreach ($attributes['atts'] as $option_id => $option_value) { if (isset($options[$option_id])) { $options[$option_id]['value'] = $option_value; } } $attributes['atts'] = fw_get_options_values_from_input($options, array()); } } return $attributes; } public function get_shortcode_data($atts = array()) { $default_width = fw_ext_builder_get_item_width($this->get_builder_type()); end($default_width); // move to the last width (usually it's the biggest) $default_width = key($default_width); $return_atts = array('width' => $default_width); if (isset($atts['atts'])) { $return_atts = array_merge($return_atts, $atts['atts']); } return array('tag' => str_replace('-', '_', $this->get_type()), 'atts' => $return_atts); } } FW_Option_Type_Builder::register_item_type('Page_Builder_Contact_Form_Item');
return $this->get_fixed_attributes($attributes); } /** * {@inheritdoc} */ public function frontend_render(array $item, $input_value) { $options = $item['options']; $attr = array('type' => 'text', 'name' => $item['shortcode'], 'placeholder' => $options['placeholder'], 'value' => is_null($input_value) ? '' : $input_value, 'id' => 'id-' . fw_unique_increment()); if ($options['required']) { $attr['required'] = 'required'; } return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'attr' => $attr)); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $options = $item['options']; $messages = array('required' => str_replace(array('{label}'), array($options['label']), __('The {label} field is required', 'fw')), 'incorrect' => str_replace(array('{label}'), array($options['label']), __('The {label} field must contain a valid email', 'fw'))); if ($options['required'] && !fw_strlen(trim($input_value))) { return $messages['required']; } if (!empty($input_value) && !filter_var($input_value, FILTER_VALIDATE_EMAIL)) { return $messages['incorrect']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Email');
* array( * 'type' => 'simple', * 'subtype' => 'button', * 'optionValues' => array( * 'size' => 'large', * 'type' => 'primary' * ) * ) * @param $registered_items Option_Type_Layout_Builder_Item[] The layout builder items, useful when * the shortcode accepts nested shortcodes * @return string The shortcode notation of the shortcode ex: [button size="large" type="primary"] */ public function get_shortcode_notation($atts, $registered_items) { $attributes = 'type="' . base64_encode($atts['subtype']) . '"'; if (isset($atts['firstInRow']) && $atts['firstInRow']) { $attributes .= ' first_in_row="' . base64_encode('true') . '"'; } $content = ''; if (!empty($atts['_items'])) { foreach ($atts['_items'] as $item) { if (!in_array($item['type'], $this->restricted_types)) { $content .= $registered_items[$item['type']]->get_shortcode_notation($item, $registered_items); } } } return "[column {$attributes}]{$content}[/column]"; } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Layout_Builder_Column_Item');
* There are saved attributes. * But we need to execute the _get_value_from_input() method for all options, * because some of them may be (need to be) changed (auto-generated) https://github.com/ThemeFuse/Unyson/issues/275 * Add the values to $option['value'] */ $options = fw_extract_only_options($options); foreach ($attributes['atts'] as $option_id => $option_value) { if (isset($options[$option_id])) { $options[$option_id]['value'] = $option_value; } } $attributes['atts'] = fw_get_options_values_from_input($options, array()); } } return $attributes; } public function get_shortcode_data($atts = array()) { $default_width = fw_ext_builder_get_item_width($this->get_builder_type()); end($default_width); // move to the last width (usually it's the biggest) $default_width = key($default_width); $return_atts = array('width' => $atts['width'] ? $atts['width'] : $default_width); if (isset($atts['atts'])) { $return_atts = array_merge($return_atts, $atts['atts']); } return array('tag' => $this->get_type(), 'atts' => $return_atts); } } FW_Option_Type_Builder::register_item_type('Page_Builder_Column_Item');
{ $options = $item['options']; $attr = array('type' => 'text', 'name' => $item['shortcode'], 'placeholder' => $options['placeholder'], 'value' => is_null($input_value) ? $options['default_value'] : $input_value, 'id' => 'id-' . fw_unique_increment()); if ($options['required']) { $attr['required'] = 'required'; } return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'attr' => $attr)); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $options = $item['options']; $messages = array('required' => str_replace(array('{label}'), array($options['label']), __('The {label} field is required', 'fw')), 'incorrect' => str_replace(array('{label}'), array($options['label']), __('The {label} field must be a valid website name', 'fw'))); if (!$options['required'] && !fw_strlen(trim($input_value))) { return null; } if ($options['required'] && !fw_strlen(trim($input_value))) { return $messages['required']; } if (!preg_match('/^https?:\\/\\//', $input_value)) { $input_value = 'http://' . $input_value; } if (!empty($input_value) && !filter_var($input_value, FILTER_VALIDATE_URL)) { return $messages['incorrect']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Website');
<?php if (!defined('FW')) { die('Forbidden'); } class Page_Builder_Row_Item extends Page_Builder_Item { public function get_type() { return 'row'; } public function enqueue_static() { } protected function get_thumbnails_data() { return array(); } public function get_value_from_attributes($attributes) { $attributes['type'] = $this->get_type(); return $attributes; } public function get_shortcode_data($atts = array()) { return array('tag' => $this->get_type()); } } FW_Option_Type_Builder::register_item_type('Page_Builder_Row_Item');
/** * @internal * {@inheritdoc} */ protected function _enqueue_static($id, $option, $data) { parent::_enqueue_static($id, $option, $data); wp_enqueue_style('fw-builder-' . $this->get_type(), fw_get_framework_directory_uri('/extensions/forms/includes/option-types/' . $this->get_type() . '/static/css/styles.css'), array('fw')); wp_enqueue_script('fw-builder-' . $this->get_type(), fw_get_framework_directory_uri('/extensions/forms/includes/option-types/' . $this->get_type() . '/static/js/helpers.js'), array('fw'), false, true); }
wp_register_script('g-recaptcha', 'https://www.google.com/recaptcha/api.js?onload=fw_forms_builder_item_recaptcha_init&render=explicit&hl=' . get_locale(), array('jquery'), null, true); wp_enqueue_script('frontend-recaptcha', $this->get_uri('/static/js/frontend-recaptcha.js'), array('g-recaptcha'), fw_ext('forms')->manifest->get_version(), true); wp_localize_script('frontend-recaptcha', 'form_builder_item_recaptcha', array('site_key' => $keys['site-key'])); return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'label' => isset($input_value['label']) ? $input_value['label'] : __('Security Code', 'fw'), 'attr' => array('class' => 'form-builder-item-recaptcha'))); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $mesages = array('not-configured' => __('Could not validate the form', 'fw'), 'not-human' => __('Please fill the recaptcha', 'fw')); $keys = fw_ext('forms')->get_db_settings_option('recaptcha-keys'); if (empty($keys)) { return $mesages['not-configured']; } $recaptcha = new ReCaptcha($keys['secret-key']); $gRecaptchaResponse = FW_Request::POST('g-recaptcha-response'); if (empty($gRecaptchaResponse)) { return $mesages['not-human']; } $resp = $recaptcha->verify($gRecaptchaResponse); if ($resp->isSuccess()) { return false; } else { $errors = $resp->getErrorCodes(); return $mesages['not-human']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Recaptcha');
} $length = fw_strlen($input_value); if ($length && !empty($options['constraints']['constraint'])) { $constraint = $options['constraints']['constraint']; $constraint_data = $options['constraints'][$constraint]; switch ($constraint) { case 'characters': if ($constraint_data['min'] && $length < $constraint_data['min']) { return sprintf($messages['characters_min_' . ($constraint_data['min'] == 1 ? 'singular' : 'plural')], $constraint_data['min']); } if ($constraint_data['max'] && $length > $constraint_data['max']) { return sprintf($messages['characters_max_' . ($constraint_data['max'] == 1 ? 'singular' : 'plural')], $constraint_data['max']); } break; case 'words': $words_length = count(preg_split('/\\s+/', $input_value)); if ($constraint_data['min'] && $words_length < $constraint_data['min']) { return sprintf($messages['words_min_' . ($constraint_data['min'] == 1 ? 'singular' : 'plural')], $constraint_data['min']); } if ($constraint_data['max'] && $words_length > $constraint_data['max']) { return sprintf($messages['words_max_' . ($constraint_data['max'] == 1 ? 'singular' : 'plural')], $constraint_data['max']); } break; default: return 'Unknown constraint: ' . $constraint; } } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Textarea');
} if (!empty($input_value) && !empty($options['constraints']['constraint'])) { $constraint = $options['constraints']['constraint']; $constraint_data = $options['constraints'][$constraint]; switch ($constraint) { case 'digits': $length = fw_strlen(str_replace(array(',', '.', '-'), '', $input_value)); if ($constraint_data['min'] && $length < $constraint_data['min']) { return sprintf($messages['digits_min_' . ($constraint_data['min'] == 1 ? 'singular' : 'plural')], $constraint_data['min']); } if ($constraint_data['max'] && $length > $constraint_data['max']) { return sprintf($messages['digits_max_' . ($constraint_data['max'] == 1 ? 'singular' : 'plural')], $constraint_data['max']); } break; case 'value': $value = doubleval($input_value); if (!is_null($constraint_data['min']) && $value < $constraint_data['min']) { return sprintf($messages['value_min'], $constraint_data['min'], $constraint_data['min'] == 1 ? '' : 's'); } if (!is_null($constraint_data['max']) && $value > $constraint_data['max']) { return sprintf($messages['value_max'], $constraint_data['max'], $constraint_data['max'] == 1 ? '' : 's'); } break; default: return 'Unknown constraint: ' . $constraint; } } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Number');
$attr['checked'] = 'checked'; } $choices[] = $attr; } if ($options['randomize']) { shuffle($choices); } return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'choices' => $choices, 'value' => $value)); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $options = $item['options']; $messages = array('required' => str_replace(array('{label}'), array($options['label']), __('The {label} field is required', 'fw')), 'not_existing_choice' => str_replace(array('{label}'), array($options['label']), __('{label}: Submitted data contains not existing choice', 'fw'))); if (empty($options['choices'])) { // the item was not displayed in frontend return; } if ($options['required'] && empty($input_value)) { return $messages['required']; } // check if has not existing choices if (!empty($input_value) && !in_array($input_value, $options['choices'])) { return $messages['not_existing_choice']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Radio');
$attr['selected'] = 'selected'; } $choices[] = $attr; } if ($options['randomize']) { shuffle($choices); } return fw_render_view($this->locate_path('/views/view.php', dirname(__FILE__) . '/view.php'), array('item' => $item, 'choices' => $choices, 'value' => $value, 'attr' => array('type' => 'select', 'name' => $item['shortcode'], 'id' => 'id-' . fw_unique_increment()))); } /** * {@inheritdoc} */ public function frontend_validate(array $item, $input_value) { $options = $item['options']; $messages = array('required' => str_replace(array('{label}'), array($options['label']), __('The {label} field is required', 'fw')), 'not_existing_choice' => str_replace(array('{label}'), array($options['label']), __('{label}: Submitted data contains not existing choice', 'fw'))); if (empty($options['choices'])) { // the item was not displayed in frontend return; } if ($options['required'] && empty($input_value)) { return $messages['required']; } // check if has not existing choices if (!empty($input_value) && !in_array($input_value, $options['choices'])) { return $messages['not_existing_choice']; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Form_Builder_Item_Select');
} /** * Transforms the array representation of the shortcode to shortcode notation * * @param $atts array The array representation of the shortcode ex: * array( * 'type' => 'simple', * 'subtype' => 'button', * 'optionValues' => array( * 'size' => 'large', * 'type' => 'primary', * ) * ) * @param $registered_items Option_Type_Layout_Builder_Item[] The layout builder items, useful when * the shortcode accepts nested shortcodes * @return string The shortcode notation of the shortcode ex: [button size="large" type="primary"] */ public function get_shortcode_notation($atts, $registered_items) { $shortcode = fw()->extensions->get('shortcodes')->get_shortcode($atts['subtype']); if ($shortcode) { $values = isset($atts['optionValues']) ? $atts['optionValues'] : array(); $shortcode_notation = $shortcode->generate_shortcode_notation($values); return $shortcode_notation; } else { return ''; } } } FW_Option_Type_Builder::register_item_type('FW_Option_Type_Layout_Builder_Simple_Item');