set_default_settings(); $forms_manager = Manager::instance(); $this->_db = $forms_manager->get_db(); $this->_table = $forms_manager->get_table(); $this->_fields = new Fields\Collection(); if (!is_null($db_params)) { $this->set_db_params($db_params); } } /** * Get default form settings * @since 2.9.5 * @return array */ public static function get_default_settings() { return [ 'name' => self::FORM_NAME_DEFAULT, //TODO: use 'title' or delete 'title' => [ 'type' => self::FORM_TITLE_DEFAULT_TYPE, 'value' => self::FORM_TITLE_DEFAULT_VALUE, ], 'status' => self::FORM_STATUS_DEFAULT, 'theme' => self::FORM_THEME_DEFAULT, 'names_position' => self::FIELD_NAME_POS_DEFAULT, 'borders_type' => self::FIELD_BORDER_DEFAULT, 'form_paddings' => self::FORM_PADDINGS_DEFAULT, 'fields_size' => self::FIELD_SIZE_DEFAULT, 'font' => [ 'family' => self::FORM_FONT_FAMILY_DEFAULT, 'size' => self::FORM_FONT_SIZE_DEFAULT, ], 'background' => [ 'type' => self::FORM_BACKGROUND_TYPE_COLOR, 'value' => self::FORM_BACKGROUND_DEFAULT_COLOR, ], 'submit' => [ 'text' => 'Submit', 'color' => self::SUBMIT_BTN_COLOR, 'size' => self::SUBMIT_BTN_SIZE_MEDIUM, ], 'email' => [ 'name' => '', 'subject' => self::FORM_NAME_DEFAULT, 'to' => (string)amoUser::instance()->get_data('login'), ], 'confirmation' => [ 'type' => self::CONFIRMATION_TYPE_TEXT, 'value' => 'Form successfully submitted!', ], 'amo' => [ 'id' => '', 'uid' => '', 'blocked' => self::FORM_BLOCKED_N, ], 'css' => self::DEFAULT_CSS_SETTINGS, 'js' => self::DEFAULT_JS_SETTINGS, ]; } /** * Set default settings. * If the key is not NULL, then only it will be applied. * @since 2.9.5 * @param string $key * @return $this */ public function set_default_settings($key = NULL) { $defaults = $this->get_default_settings(); if (is_null($key)) { $this->_settings = $defaults; } elseif (array_key_exists($key, $defaults)) { $this->_settings[$key] = $defaults[$key]; } return $this; } /** * Set default fields * @since 1.0.0 * * @return $this * @throws Argument */ public function set_default_fields() { $this->_fields ->delete_all() ->add(new Fields\Types\Name()) ->add(new Fields\Types\Email()) ->add(new Fields\Types\Textarea()) ; return $this; } /** * Set form params form db params * @since 1.0.0 * * @param array $db_params - row of params from DB * @return $this * @throws Argument * @throws Runtime */ protected function set_db_params(array $db_params) { if (empty($db_params['id'])) { throw new Argument('Invalid form id'); } if (empty($db_params['settings']) || empty($db_params['fields'])) { throw new Argument('Invalid form db params'); } $db_params['settings'] = json_decode($db_params['settings'], TRUE); $db_params['fields'] = json_decode($db_params['fields'], TRUE); if (empty($db_params['settings']) || !is_array($db_params['settings']) || !isset($db_params['fields']) || !is_array($db_params['fields'])) { throw new Runtime('Error decoding form params'); } $migration = Migration::instance(); if ($need_migrate = $migration->need_migrate($db_params)) { $db_params = $migration->migrate($db_params); } $this ->set_id($db_params['id']) ->set_settings($db_params['settings']) ->set_fields($db_params['fields']); if ($need_migrate) { $this->save(); } return $this; } /** * Set form settings * @since 1.0.0 * * @param array $settings * @return $this * @throws Runtime */ public function set_settings(array $settings) { foreach ($this->_settings as $key => $value) { if (isset($settings[$key])) { $method = "set_$key"; if (!method_exists($this, $method)) { throw new Runtime("Method '{$method}' not exists in " . __CLASS__); } $this->$method($settings[$key]); } } return $this; } /** * Set fields by their params form db/request * @since 1.0.0 * * @param array $fields_params * @return $this * @throws \Amoforms\Exceptions\Validate */ public function set_fields(array $fields_params) { $this->_fields->fill_by_params($fields_params); return $this; } /** * Fill empty settings * @since 1.1.0 */ protected function fill_settings() { //TODO: find, why function "wp_get_current_user" not exists sometimes if (!function_exists('wp_get_current_user')) { return; } /** @var \WP_User $user */ $user = wp_get_current_user(); if (empty($this->_settings['email']['name'])) { $this->set_email(['name' => $user->display_name]); } /* temporary disabled if (empty($this->_settings['email']['to'])) { $this->set_email(['to' => $user->user_email]); } */ } /** * Create/update form on forms.amoCRM.com * @since 2.6.0 */ private function amo_update() { $amo_user = amoUser::instance(); if (!$amo_user->is_full()) { return; } $amo_forms = Forms::instance(); $credentials = $this->get('amo'); $top_level_domain = $amo_user->get_param(amoUser::PARAM_TOP_LEVEL_DOMAIN); if (empty($credentials['id'])) { list($id, $uid) = $amo_forms->register_form( $amo_user->get_data('subdomain'), $amo_user->get_data('login'), $amo_user->get_data('api_key'), $amo_user->get_primary_authorization_type(), $top_level_domain ); $this->set_amo(['id' => $id, 'uid' => $uid]); } else { $amo_forms->update_form( $credentials['id'], $credentials['uid'], $amo_user->get_data('subdomain'), $amo_user->get_data('login'), $amo_user->get_data('api_key'), $amo_user->get_primary_authorization_type(), $top_level_domain ); } } /** * Duplicate form, save it to DB and return new instance. * @since 2.9.5 * @return Form - new Form instance * @throws Runtime */ public function duplicate() { $form = clone $this; $form->_id = NULL; $form->set_default_settings('amo')->save(); return $form; } /** * Save form to database * @since 1.0.0 * * @return $this * @throws Runtime */ public function save() { $this->fill_settings(); //FIXME: move to another place because it slows down ajax while editing fields: $this->amo_update(); $data = new Query_Data([ 'settings' => ['%s', json_encode(Helpers::strip_slashes($this->get_settings()), JSON_UNESCAPED_UNICODE)], 'fields' => ['%s', json_encode(Helpers::strip_slashes($this->_fields->get_for_save()), JSON_UNESCAPED_UNICODE)], 'version' => ['%s', AMOFORMS_VERSION], ]); if ($this->id()) { if ($this->_db->update($this->_table, $data->get_data(), ['id' => $this->id()], $data->get_formats()) === FALSE) { throw new Runtime('Error saving form to db'); } } else { $this->_db->insert($this->_table, $data->get_data(), $data->get_formats()); $form_id = $this->_db->insert_id; if (!$form_id) { throw new Runtime("Can't get id of inserted form"); } $this->set_id($form_id); } return $this; } /** * Add field to form * @param Base_Field $field * @param int $position * @return $this * @throws Argument */ public function add_field(Base_Field $field, $position = NULL) { if (is_null($position)) { $this->_fields->add($field); } else { $this->_fields->insert($field, $position); } return $this; } /** * Duplicate field * @param int $id * @return Base_Field|bool */ public function duplicate_field($id) { return $this->_fields->duplicate($id); } /** * Edit field * @param int $id * @param array $params * @return $this * @throws Runtime */ public function edit_field($id, array $params) { /** @var Base_Field $field */ if (!$field = $this->_fields->get_by_id($id)) { throw new Runtime('Field not found'); } $field->set_params($params); return $this; } /** * Delete field form form * @param int $id * @throws Argument * @return $this */ public function delete_field($id) { $this->_fields->delete((int)$id); return $this; } /** * Check for existing captcha field in form. * @since 2.11.0 * @return bool */ public function has_captcha() { foreach ($this->get_fields() as $field) { if ($field['type'] === Fields\Types\Base_Field::TYPE_CAPTCHA) { return TRUE; } } return FALSE; } public function is_blocked() { return $this->get('amo', 'blocked') === self::FORM_BLOCKED_Y; } public function get($key, $sub_key = NULL) { $result = isset($this->_settings[$key]) ? $this->_settings[$key] : FALSE; if (!is_null($sub_key)) { $result = is_array($result) && isset($result[$sub_key]) ? $result[$sub_key] : NULL; } return $result; } /** * Get all settings * @return array */ public function get_settings() { return $this->_settings; } /** * Get fields as array * @return array */ public function get_fields() { return $this->_fields->to_array(); } /** * @return array */ public function get_title_types() { return $this->_title_types; } /** * @return array */ public function get_confirmation_types() { return $this->_confirmation_types; } /** * @return array */ public function get_statuses_types() { return $this->_statuses_types; } /** * @since 2.6.1 * @return array */ public function get_submit_sizes() { return [ self::SUBMIT_BTN_SIZE_SMALL, self::SUBMIT_BTN_SIZE_MEDIUM, self::SUBMIT_BTN_SIZE_LARGE, ]; } /** * Get id * @since 1.0.0 * @return int|null */ public function id() { return $this->_id; } /** * @param int $id * @return $this */ protected function set_id($id) { $this->_id = abs((int)$id); return $this; } /** * @param string $name * @return $this */ protected function set_name($name) { $this->_settings['name'] = Strings::escape($name); return $this; } /** * @param array $title * @return $this */ protected function set_title(array $title) { if (!empty($title['type']) && in_array($title['type'], $this->_title_types, TRUE)) { $this->_settings['title']['type'] = $title['type']; } if (!empty($title['value'])) { $this->_settings['title']['value'] = Strings::escape($title['value']); } return $this; } /** * @param string $status * @return $this */ protected function set_status($status) { if (in_array($status, $this->_statuses_types, TRUE)) { $this->_settings['status'] = $status; } return $this; } /** * @param int $theme - theme id * @return $this */ protected function set_theme($theme) { $this->_settings['theme'] = abs((int)$theme); //TODO: check for valid value return $this; } /** * @param string $form_paddings * @return $this */ protected function set_form_paddings($form_paddings) { if (in_array($form_paddings, $this->_form_paddings, TRUE)) { $this->_settings['form_paddings'] = $form_paddings; } return $this; } /** * @param string $position * @return $this */ protected function set_names_position($position) { if (in_array($position, $this->_names_positions, TRUE)) { $this->_settings['names_position'] = $position; } return $this; } /** * @param string $type * @return $this */ protected function set_borders_type($type) { if (in_array($type, $this->_fields_borders_types, TRUE)) { $this->_settings['borders_type'] = $type; } return $this; } /** * @param int $size * @return $this */ protected function set_fields_size($size) { $size = abs((int)$size); if ($size >= self::FIELD_SIZE_MIN && $size <= self::FIELD_SIZE_MAX) { $this->_settings['fields_size'] = $size; } return $this; } /** * @param array $font * @return $this */ protected function set_font($font) { if ($font && is_array($font)) { if (!empty($font['family']) && in_array($font['family'], $this->_available_fonts, TRUE)) { $this->_settings['font']['family'] = $font['family']; } //TODO: add size validation if (!empty($font['size'])) { $this->_settings['font']['size'] = abs((int)$font['size']); } } return $this; } /** * @param array $background * @return $this */ protected function set_background(array $background) { if (!empty($background['type']) && in_array($background['type'], $this->_background_types, TRUE)) { $this->_settings['background']['type'] = $background['type']; } if (!empty($background['value'])) { $this->_settings['background']['value'] = Strings::escape($background['value']); } return $this; } /** * @since 2.17.0 * @param string $css * @return $this */ protected function set_css($css) { if (($css = Strings::sanitize_css($css)) !== FALSE) { $this->_settings['css'] = $css; } return $this; } /** * @since 2.17.0 * @param string $js * @return $this */ protected function set_js($js) { if (is_string($js)) { $this->_settings['js'] = $js; } return $this; } /** * @since 2.6.0 * @param array $values * @return $this */ public function set_amo(array $values) { foreach (array_keys($this->_settings['amo']) as $field) { if (!empty($values[$field])) { $this->_settings['amo'][$field] = $values[$field]; } } return $this; } /** * @since 2.6.0 * @param array $settings * @return $this */ protected function set_submit(array $settings) { foreach ($this->_settings['submit'] as $key => $value) { if (!empty($settings[$key])) { if ($key === 'size') { $value = (int)$settings[$key]; if (in_array($value, $this->get_submit_sizes(), TRUE)) { $this->_settings['submit'][$key] = $value; } } else { $this->_settings['submit'][$key] = Strings::escape($settings[$key]); } } } return $this; } /** * Set email settings * @since 1.0.0 * @param array $email_settings * @return $this */ protected function set_email(array $email_settings) { foreach ($this->_settings['email'] as $key => $old_value) { if (!empty($email_settings[$key])) { if ($key === 'email' && !filter_var($email_settings[$key], FILTER_VALIDATE_EMAIL)) { continue; } $this->_settings['email'][$key] = Strings::escape($email_settings[$key]); } } return $this; } /** * @since 1.0.0 * @param array $page_settings * @return $this */ protected function set_page(array $page_settings) { foreach ($this->_settings['page'] as $key => $value) { if (isset($page_settings[$key])) { $this->_settings['page'][$key] = (bool)$page_settings[$key]; } } return $this; } /** * @since 1.0.0 * @param array $confirmation * @return $this */ protected function set_confirmation(array $confirmation) { if (!empty($confirmation['type']) && in_array($confirmation['type'], $this->_confirmation_types, TRUE)) { $this->_settings['confirmation']['type'] = $confirmation['type']; } if (isset($confirmation['value'])) { $this->_settings['confirmation']['value'] = Strings::escape($confirmation['value']); } return $this; } /** * @since 2.18.5 * @return array|FALSE */ protected function get_captcha_field() { foreach ($this->get_fields() as $field) { if ($field['type'] === Fields\Types\Base_Field::TYPE_CAPTCHA) { return $field; } } return FALSE; } /** * @since 2.18.5 * @return bool */ public function is_need_captcha_ntp() { if ($field = $this->get_captcha_field()) { return (isset($field['options']['captcha_ntp']) && $field['options']['captcha_ntp'] === Fields\Types\Base_Field::CAPTCHA_NTP_ENABLED); } return FALSE; } }