endOwnerMails(); if ( 'translate' !== swiftling_mode() || ! is_array( $settings ) || ! (int) $form_id || ! (int) $action_id ) { return $settings; } $type = isset( $settings['type'] ) ? (string) $settings['type'] : ''; if ( 'email' === $type && ! self::mailsTheVisitor( $settings ) ) { $this->startOwnerMail(); return $settings; } return $this->translateAction( (int) $form_id, (int) $action_id, $settings ); } /** * Ends the sending of a form: an email to the site's owner sent last is done. */ public function endActions(): void { $this->endOwnerMails(); } /** * Translates the texts of an action: the message after sending, or the subject and text of an * email. Other actions have none. * * @param int $form_id Form ID. * @param int $action_id Action ID. * @param array $settings Settings of the action. */ private function translateAction( int $form_id, int $action_id, array $settings ): array { $type = isset( $settings['type'] ) ? (string) $settings['type'] : ''; $names = 'successmessage' === $type ? array( 'success_msg' ) : ( 'email' === $type ? self::MAIL_TEXTS : array() ); $places = array(); foreach ( $names as $name ) { self::addPlace( $places, $settings, array( $name ), 'actions/a' . $action_id . '/' . $name ); } return $this->translate( $form_id, $settings, $places ); } /** * Whether an email action writes to the visitor: every address it sends to is a field's tag, as * {field:email}, or the signed-in visitor's own. The site's address, {wp:admin_email} or * {system:admin_email}, a post author's and a fixed address are the site owner's. * * @param array $settings Settings of the email action. */ private static function mailsTheVisitor( array $settings ): bool { return self::onlyVisitors( isset( $settings['to'] ) && is_string( $settings['to'] ) ? $settings['to'] : '', static function ( string $recipient ): bool { return 1 === preg_match( '/^\{(field:[^{}]+|wp:user_email|user:email)\}$/', $recipient ); } ); } /** * Translates the texts of the settings of a form. * * @param mixed $settings Settings of the form. * @param int|string $form_id Form ID. * @return mixed */ public function filterSettings( $settings, $form_id ) { if ( ! is_array( $settings ) || ! (int) $form_id ) { return $settings; } $places = array(); foreach ( self::FORM_TEXTS as $name ) { self::addPlace( $places, $settings, array( $name ), $name ); } return $this->translate( (int) $form_id, $settings, $places ); } /** * Translates the title of a form the plugin prints itself, as the title in its settings. * * @param mixed $title Title. * @param int|string $form_id Form ID. * @return mixed */ public function filterTitle( $title, $form_id ) { if ( ! is_string( $title ) || ! (int) $form_id ) { return $title; } $places = array(); self::addPlace( $places, array( 'title' => $title ), array( 'title' ), 'title' ); return $this->translate( (int) $form_id, array( 'title' => $title ), $places )['title']; } /** * Translates the texts of the fields of a form. * * @param mixed $fields Fields: the settings of each, with its ID. * @param int|string $form_id Form ID. * @return mixed */ public function filterFields( $fields, $form_id ) { if ( ! is_array( $fields ) || ! (int) $form_id ) { return $fields; } $places = array(); foreach ( $fields as $index => $field ) { if ( ! is_array( $field ) || ! isset( $field['id'] ) ) { continue; } // A form shown twice on a page has its fields numbered "1_1"; their texts stay field 1's. $id = 'fields/field_' . (int) $field['id']; $type = isset( $field['type'] ) ? (string) $field['type'] : ''; foreach ( self::FIELD_TEXTS as $name ) { if ( 'label' !== $name || ! in_array( $type, self::NO_LABEL, true ) ) { self::addPlace( $places, $fields, array( $index, $name ), $id . '/' . $name ); } } if ( 'html' === $type ) { self::addPlace( $places, $fields, array( $index, 'default' ), $id . '/content' ); } $options = isset( $field['options'] ) && is_array( $field['options'] ) ? $field['options'] : array(); foreach ( array_keys( $options ) as $row ) { self::addPlace( $places, $fields, array( $index, 'options', $row, 'label' ), $id . '/options/o' . $row . '/label' ); } } return $this->translate( (int) $form_id, $fields, $places ); } /** * Returns the forms. * * @return array */ protected function allForms(): array { $forms = array(); foreach ( Ninja_Forms()->form()->get_forms() as $model ) { $forms[] = array( 'id' => (int) $model->get_id(), 'title' => trim( (string) $model->get_setting( 'title' ) ), ); } return $forms; } /** * Returns the settings of a form, as the plugin's model gives them. * * @param int $form_id Form ID. */ protected function formSettings( int $form_id ): array { return (array) Ninja_Forms()->form( $form_id )->get()->get_settings(); } /** * Returns the fields of a form, each its settings with its ID, as the plugin's models give them. * * @param int $form_id Form ID. */ protected function formFields( int $form_id ): array { $fields = array(); foreach ( Ninja_Forms()->form( $form_id )->get_fields() as $model ) { $fields[] = array( 'id' => (int) $model->get_id() ) + (array) $model->get_settings(); } return $fields; } /** * Returns the actions of a form, each its ID and its settings, as the plugin's models give them. * * @param int $form_id Form ID. * @return array */ protected function formActions( int $form_id ): array { $actions = array(); foreach ( Ninja_Forms()->form( $form_id )->get_actions() as $model ) { $actions[] = array( 'id' => (int) $model->get_id(), 'settings' => (array) $model->get_settings(), ); } return $actions; } /** * Reads the texts of a form through the filters, as a page that shows it and the sending of it * do: its settings, its fields, the message after sending and the emails to the visitor. * * @param int $form_id Form ID. */ protected function readTexts( int $form_id ): void { $this->filterSettings( $this->formSettings( $form_id ), $form_id ); $this->filterFields( $this->formFields( $form_id ), $form_id ); foreach ( $this->formActions( $form_id ) as $action ) { $type = isset( $action['settings']['type'] ) ? (string) $action['settings']['type'] : ''; if ( 'email' !== $type || self::mailsTheVisitor( $action['settings'] ) ) { $this->translateAction( $form_id, (int) $action['id'], $action['settings'] ); } } } /** * Returns the ways a post shows a form: the shortcode, or the block with the ID of the form, * which the block saves as a number. * * @param int $form_id Form ID. * @return array */ protected function pageMarks( int $form_id ): array { $marks = array(); foreach ( array( 'ninja_form', 'ninja_forms' ) as $tag ) { foreach ( array( $form_id . ']', $form_id . ' ', '"' . $form_id . '"', "'" . $form_id . "'" ) as $id ) { $marks[] = array( '[' . $tag . ' id=' . $id ); } } foreach ( array( $form_id . ',', $form_id . '}', '"' . $form_id . '"' ) as $id ) { $marks[] = array( '