8889841cexceptions/action-validation-failed-exception.php000064400000000532150515351440016264 0ustar00action, $message ); } } exceptions/action-failed-exception.php000064400000000513150515351440014133 0ustar00action, $message ); } } exceptions/exception-base.php000064400000002471150515351440012353 0ustar00action = $action; $this->meta = $meta; $message = $this->format_message( $message ); parent::__construct( $message ); } /** * Log the exception to Elementor's log. * * @return void */ public function log() { Plugin::elementor()->logger->get_logger()->error( $this->getMessage(), [ 'meta' => $this->meta ] ); } /** * Get the error format. * * @return string */ public function __toString() { return sprintf( '%s: %s', __CLASS__, $this->getMessage() ); } } actions/email/email.php000064400000005321150515351440011077 0ustar00content_type ), sprintf( 'From: %s', $payload->from->format() ), ]; foreach ( $payload->reply_to as $recipient ) { $headers[] = sprintf( 'Reply-To: %s', $recipient->format() ); } // Set CC headers. $cc_headers = []; foreach ( $payload->cc as $recipient ) { $cc_headers[] = sprintf( 'Cc: %s', $recipient->format() ); } // Send email. $this->send_mail( $payload->to->format(), $payload->subject, $payload->body, implode( PHP_EOL, array_merge( $headers, $cc_headers ) ), $payload->attachments ); // Send BCC emails. foreach ( $payload->bcc as $bcc ) { $this->send_mail( $bcc->format(), $payload->subject, $payload->body, implode( PHP_EOL, $headers ), $payload->attachments ); } } /** * @alias `$this->run()` * * @param Email_Message $payload * * @return void *@throws \Exception * */ public function send( Email_Message $payload ) { $this->run( $payload ); } /** * Validate the email message DTO. * * @param Email_Message $payload * * @throws \ElementorPro\Core\Integrations\Exceptions\Action_Validation_Failed_Exception * * @return void */ public function validate( $payload ) { $required_fields = [ 'from', 'to', 'subject', 'body', 'content_type', ]; foreach ( $required_fields as $field ) { if ( empty( $payload->{$field} ) ) { throw new Action_Validation_Failed_Exception( static::class, "`Email_Message::\${$field}` is required." ); } } } /** * Calls `wp_mail()`. Used for testing. * * @param mixed ...$args * * @return void */ protected function send_mail( ...$args ) { add_action( 'wp_mail_failed', [ $this, 'on_wp_mail_error' ] ); wp_mail( ...$args ); remove_action( 'wp_mail_failed', [ $this, 'on_wp_mail_error' ] ); } /** * Throw exception on `wp_mail()` error. * * @param \WP_Error $error * * @throws \ElementorPro\Core\Integrations\Exceptions\Action_Failed_Exception * * @return void */ public function on_wp_mail_error( \WP_Error $error ) { throw new Action_Failed_Exception( static::class, '`wp_mail()` cannot send email', $error ); } } actions/email/email-message.php000064400000010015150515351440012515 0ustar00from( get_bloginfo( 'admin_email' ), get_bloginfo( 'name' ) ); } /** * Set the email sender. * * @param string $email * @param string|null $name * * @return $this */ public function from( $email, $name = null ) { $this->from = new Email_Address( $email, $name ); return $this; } /** * Set the email recipient. * * @param string $email * @param string|null $name * * @return $this */ public function to( $email, $name = null ) { $this->to = new Email_Address( $email, $name ); return $this; } /** * Add a reply to. * * @param string $email * @param string|null $name * * @return $this */ public function reply_to( $email, $name = null ) { $this->reply_to[] = new Email_Address( $email, $name ); return $this; } /** * Add a CC. * * @param string $email * @param string|null $name * * @return $this */ public function cc( $email, $name = null ) { $this->cc[] = new Email_Address( $email, $name ); return $this; } /** * Add a BCC. * * @param string $email * @param string|null $name * * @return $this */ public function bcc( $email, $name = null ) { $this->bcc[] = new Email_Address( $email, $name ); return $this; } /** * Set the email subject. * * @param string $subject * * @return $this */ public function subject( $subject ) { $this->subject = (string) $subject; return $this; } /** * Set the email content type. * * @param string $content_type * * @return $this */ public function content_type( $content_type ) { $this->content_type = (string) $content_type; return $this; } /** * Set the email body using plain text. * * @param string $body * @param string $content_type * * @return $this */ public function body( $body, $content_type = 'text/html' ) { $this->body = (string) $body; return $this->content_type( $content_type ); } /** * Set the email body using a view. * * @param string $path - View path, * @param array $data - Data that will be passes to the view. * * @return $this * @throws \Exception */ public function view( $path, $data = [] ) { if ( ! is_file( $path ) ) { throw new \Exception( "`{$path}` is not a valid view." ); } ob_start(); // Inspired from Laravel's view mechanism: // [1] https://github.dev/illuminate/filesystem/blob/b179f9ea3b3195d1f4b5ae2aee67e42eac6ceb5e/Filesystem.php#L98 // [2] https://github.dev/illuminate/view/blob/6dd315634a44450c5e443fa8735d4a526833fad3/Engines/PhpEngine.php#L48 call_user_func( function( $__view_path, $__view_data ) { extract( $__view_data, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract unset( $__view_data ); // `$__view_data` keys are available in the file as variables. require $__view_path; }, $path, $data ); $this->body = ob_get_clean(); return $this->content_type( 'text/html' ); } /** * Add an attachment. * * @param string $path - Attachment path on the server. * * @return $this */ public function attach( $path ) { $this->attachments[] = (string) $path; return $this; } } actions/email/email-address.php000064400000001526150515351440012525 0ustar00address = (string) $address; $this->name = (string) $name; } /** * Format an email to be ready for header (e.g. `Recipient Name ` or `user@email.com`) * * @return string */ public function format() { if ( ! empty( $this->name ) ) { return sprintf( '%s <%s>', $this->name, $this->address ); } return sprintf( '%s', $this->address ); } } actions/action-base.php000064400000002012150515351440011100 0ustar00validate( $payload ); $this->apply( $payload ); } } integrations-manager.php000064400000005343150515351440011403 0ustar00actions_registrar = new Registrar(); } /** * Get an action instance. * * @shortcut `Registrar->get()`. * * @return \ElementorPro\Core\Integrations\Actions\Action_Base|null */ public function get_action( $id ) { if ( ! $this->is_initialized() ) { $this->init_actions(); } return $this->actions_registrar->get( $id ); } /** * Run an action for a selected payload. * * @param array|mixed $payloads - Payloads instances to run the actions on. * @param null|string $id - If `$payloads` is not an array, a custom action ID can be provided. * * @return void */ public function run( $payloads, $id = null ) { if ( ! is_array( $payloads ) ) { $payloads = $id ? [ $id => $payloads ] : [ $payloads ]; } foreach ( $payloads as $key => $payload ) { // Get the action ID for the provided payload type. $action_id = is_numeric( $key ) ? get_class( $payload ) : $key; /** * @type Action_Base $action */ $action = $this->get_action( $action_id ); if ( ! $action ) { throw new \Exception( "{$action_id} doesn't have an associated `Action`." ); } if ( ! ( $action instanceof Action_Base ) ) { $action_class = get_class( $action ); throw new \Exception( "{$action_class} is not a valid `Action_Base`." ); } try { $action->run( $payload ); } catch ( Action_Validation_Failed_Exception $e ) { $e->log(); } catch ( Action_Failed_Exception $e ) { $e->log(); } } } /** * Initialize the manager actions. * * @return void */ protected function init_actions() { add_action( 'elementor_pro/core/integrations/actions/register', function ( Registrar $actions_registrar ) { $actions_registrar->register( new Email(), Email_Message::class ); } ); do_action( 'elementor_pro/core/integrations/actions/register', $this->actions_registrar ); } /** * Determine if the manager is initialized. * * @return boolean */ protected function is_initialized() { return ! ! did_action( 'elementor_pro/core/integrations/actions/register' ); } }