Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 35 additions & 35 deletions forms-bridge/addons/listmonk/class-listmonk-addon.php
Original file line number Diff line number Diff line change
Expand Up @@ -159,43 +159,43 @@ public function get_endpoint_schema( $endpoint, $backend, $method = null ) {
}
}

if ( '/api/subscribers' === $endpoint ) {
return array(
array(
'name' => 'email',
'schema' => array( 'type' => 'string' ),
'required' => true,
),
array(
'name' => 'name',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'status',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'lists',
'schema' => array(
'type' => 'array',
'items' => array( 'type' => 'number' ),
),
),
array(
'name' => 'preconfirm_subscriptions',
'schema' => array( 'type' => 'boolean' ),
),
array(
'name' => 'attribs',
'schema' => array(
'type' => 'object',
'properties' => array(),
),
),
);
if ( '/api/subscribers' !== $endpoint ) {
return array();
}

return array();
return array(
array(
'name' => 'email',
'schema' => array( 'type' => 'string' ),
'required' => true,
),
array(
'name' => 'name',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'status',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'lists',
'schema' => array(
'type' => 'array',
'items' => array( 'type' => 'number' ),
),
),
array(
'name' => 'preconfirm_subscriptions',
'schema' => array( 'type' => 'boolean' ),
),
array(
'name' => 'attribs',
'schema' => array(
'type' => 'object',
'properties' => array(),
),
),
);
}
}

Expand Down
1 change: 1 addition & 0 deletions forms-bridge/addons/nextcloud/class-nextcloud-addon.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ static function ( $prune, $bridge ) {
2
);
}

/**
* Performs a request against the backend to check the connexion status.
*
Expand Down
Binary file added forms-bridge/addons/zulip/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
187 changes: 187 additions & 0 deletions forms-bridge/addons/zulip/class-zulip-addon.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php
/**
* Class Zulip_Addon
*
* @package formsbridge
*/

namespace FORMS_BRIDGE;

use Exception;

if ( ! defined( 'ABSPATH' ) ) {
exit();
}

require_once 'class-zulip-form-bridge.php';
require_once 'hooks.php';

/**
* Zulip addon class
*/
class Zulip_Addon extends Addon {

/**
* Holds the addon's title.
*
* @var string
*/
public const TITLE = 'Zulip';

/**
* Holds the addon's name.
*
* @var string
*/
public const NAME = 'zulip';

/**
* Holds the addon's custom bridge class.
*
* @var string
*/
public const BRIDGE = '\FORMS_BRIDGE\Zulip_Form_Bridge';

/**
* Holds the Zulip OAS public URL.
*
* @var string
*/
public const OAS_URL = 'https://raw.githubusercontent.com/zulip/zulip/refs/heads/main/zerver/openapi/zulip.yaml';

/**
* Performs a request against the backend to check the connexion status.
*
* @param string $backend Backend name.
*
* @return boolean
*/
public function ping( $backend ) {
$bridge = new Zulip_Form_Bridge(
array(
'name' => '__zulip-' . time(),
'endpoint' => '/api/v1/streams',
'method' => 'GET',
'backend' => $backend,
),
'zulip'
);

$response = $bridge->submit();

if ( is_wp_error( $response ) ) {
Logger::log( 'Zulip backend ping error response', Logger::ERROR );
Logger::log( $response, Logger::ERROR );
return false;
}

return true;
}

/**
* Performs a GET request against the backend endpoint and retrive the response data.
*
* @param string $endpoint API endpoint.
* @param string $backend Backend name.
*
* @return array|WP_Error
*/
public function fetch( $endpoint, $backend ) {
$bridge = new Zulip_Form_Bridge(
array(
'name' => '__zulip-' . time(),
'endpoint' => $endpoint,
'method' => 'GET',
'backend' => $backend,
),
'zulip'
);

return $bridge->submit();
}

/**
* Performs an introspection of the backend endpoint and returns API fields.
*
* @param string $endpoint API endpoint.
* @param string $backend Backend name.
* @param string|null $method HTTP method.
*
* @return array List of fields and content type of the endpoint.
*/
public function get_endpoint_schema( $endpoint, $backend, $method = null ) {
if ( function_exists( 'yaml_parse' ) ) {
$response = wp_remote_get( self::OAS_URL );

if ( ! is_wp_error( $response ) ) {
$data = yaml_parse( $response['body'] );

if ( $data ) {
try {
$oa_explorer = new OpenAPI( $data );

$method = strtolower( $method ?? 'post' );
$path = preg_replace( '', '', $endpoint );
$source = in_array( $method, array( 'post', 'put', 'patch' ), true ) ? 'body' : 'query';
$params = $oa_explorer->params( $path, $method, $source );

return $params ?: array();
} catch ( Exception ) {
// do nothing.
}
}
}
}

if ( '/api/v1/messages' !== $endpoint ) {
return array();
}

return array(
array(
'name' => 'type',
'schema' => array(
'type' => 'string',
'enum' => array( 'direct', 'stream' ),
),
'required' => true,
),
array(
'name' => 'to',
'schema' => array(
'type' => 'array',
'items' => array(
'type' => array( 'string', 'integer' ),
),
),
'required' => true,
),
array(
'name' => 'content',
'schema' => array( 'type' => 'string' ),
'required' => true,
),
array(
'name' => 'topic',
'schema' => array(
'type' => 'string',
'default' => '(no topic)',
),
),
array(
'name' => 'queue_id',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'local_id',
'schema' => array( 'type' => 'string' ),
),
array(
'name' => 'read_by_sender',
'schema' => array( 'type' => 'boolean' ),
),
);
}
}

Zulip_Addon::setup();
69 changes: 69 additions & 0 deletions forms-bridge/addons/zulip/class-zulip-form-bridge.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* Class Zulip_Form_Bridge
*
* @package formsbridge
*/

namespace FORMS_BRIDGE;

use FBAPI;
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) {
exit();
}

/**
* Form bridge implamentation for the Zulip API.
*/
class Zulip_Form_Bridge extends Form_Bridge {

/**
* Submits payload and attachments to the bridge's backend.
*
* @param array $payload Payload data.
* @param array $attachments Submission's attached files.
*
* @return array|WP_Error Http request response.
*/
public function submit( $payload = array(), $attachments = array() ) {
$uploads = FBAPI::get_uploads();

if ( ! empty( $uploads ) ) {
$backend = $this->backend()->clone(
array(
'headers' => array(
array(
'name' => 'Content-Type',
'value' => 'multipart/form-data',
),
),
)
);

$annex = "\n\n----\n" . esc_html( __( 'Attachments', 'forms-bridge' ) ) . ":\n";

$attachments = Forms_Bridge::attachments( $uploads );

foreach ( $attachments as $name => $path ) {
$response = $backend->post( '/api/v1/user_uploads', array(), array(), array( $name => $path ) );

if ( is_wp_error( $response ) ) {
return $response;
} elseif ( 'success' !== $response['data']['result'] ) {
return new WP_Error( 'zulip_upload', __( 'Can not upload a file to Zulip', 'forms-bridge' ), $response['data'] );
}

unset( $payload[ $name ] );
unset( $payload[ $name . '_filename' ] );

$annex .= "* [{$name}]({$response['data']['url']})\n";
}

$payload['content'] .= $annex;
}

return parent::submit( $payload, array() );
}
}
Loading