-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop', bump version to 0.1.0
- Loading branch information
Showing
109 changed files
with
10,472 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
name: Build release files | ||
|
||
on: | ||
push: | ||
tags: "*" | ||
release: | ||
types: [created] | ||
|
||
jobs: | ||
build-zip: | ||
name: Build plugin ZIP file | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
|
||
- name: Setup PHP | ||
uses: shivammathur/setup-php@v2 | ||
with: | ||
php-version: "7.2" | ||
|
||
- name: Install Composer dependencies | ||
uses: ramsey/composer-install@v2 | ||
with: | ||
composer-options: "--no-dev --optimize-autoloader" | ||
|
||
- name: Build ZIP file | ||
run: ./build-aux/build-zip.sh | ||
|
||
- name: Upload release files | ||
uses: svenstaro/upload-release-action@v2 | ||
with: | ||
repo_token: ${{ secrets.GITHUB_TOKEN }} | ||
file: build/limesurvey-rest-api.zip | ||
asset_name: limesurvey-rest-api.zip | ||
tag: ${{ github.ref }} | ||
prerelease: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/vendor/ | ||
|
||
/build/* | ||
!/build/.gitkeep |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# LimeSurvey REST API | ||
|
||
A [LimeSurvey](https://github.com/LimeSurvey/LimeSurvey) plugin providing RESTful API. It's a (yet-incomplete) replacement for LimeSurvey's built-in JSON RPC interface. | ||
|
||
## Features | ||
|
||
The main features are: | ||
|
||
- 🤩 **Simple and intuitive.** Start using and see. | ||
|
||
- 🖹 **Properly documented.** With the help of a proper OpenAPI spec, an up-to-date documentation is always in front of your eyes. It should help you even if you're not familiar with LS core. | ||
|
||
- 🔍 **Strong validation.** Plus automatic spec-based validation (which is cached for performance) thanks to [openapi-psr7-validator](https://github.com/thephpleague/openapi-psr7-validator), it relies on validations done by the core (and providing extra validations when needed). It also supports the LS permission model. | ||
|
||
- 📦 **Docker-ready.** It auto-registers and activates itself on LimeSurvey, e.g. making it easy to be used in [limesurvey-docker](https://github.com/adamzammit/limesurvey-docker). | ||
|
||
## Requirements | ||
|
||
- LimeSurvey >= 5.3 | ||
- PHP >= 7.2 | ||
|
||
## How to Install? | ||
|
||
Download the latest ZIP file from [Releases](https://github.com/machitgarha/limesurvey-rest-api/releases). Then in LimeSurvey, from the top bar, click on "Configuration", go to "Plugins", click on "Upload and install" at the top, and select the downloaded file. | ||
|
||
### Updating | ||
|
||
Repeat the steps above to update the plugin, with one more step: You have to deactivate and activate the plugin for the cache to be cleared. | ||
|
||
## Documentation | ||
|
||
You can generate the documentation using any OpenAPI documentation generator. We recommend using [redoc-cli](https://github.com/Redocly/redoc). | ||
|
||
Example of generating the docs using it: | ||
|
||
```sh | ||
redoc-cli build spec/openapi.yaml -o build/docs.html | ||
``` | ||
|
||
Running this, you can use the HTML file (`build/docs.html`) as documentation. | ||
|
||
## What is Implemented? | ||
|
||
This plugin has limited functionality, i.e. it doesn't provide an endpoint for all actions. It however provides the required functionality for filling survey answers. | ||
|
||
More precisely, you can log in as a user, get the information of surveys, their questions and question groups, and send responses for surveys. Note that, for responses, all question types are supported. | ||
|
||
## Contributions, Please! :) | ||
|
||
I kindly ask you that, if you have time and the ability to complete unimplemented parts, or fix or implement one of the [issues](https://github.com/machitgarha/limesurvey-rest-api/issues), then start doing so, we'll appreciate your effort for sure (and everyone will benefit from it). | ||
|
||
## License | ||
|
||
[GPLv2](./LICENSE.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<?php | ||
|
||
require __DIR__ . "/vendor/autoload.php"; | ||
|
||
use MAChitgarha\LimeSurveyRestApi\Plugin; | ||
|
||
class RestApi extends Plugin | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
#!/bin/sh | ||
|
||
# Config | ||
pluginName="RestApi" | ||
outputFile="build/limesurvey-rest-api.zip" | ||
|
||
# Exit on error | ||
set -e | ||
|
||
mainRepoDir="$(dirname "$(realpath "$0/..")")" | ||
# The resulting file path | ||
zipFilePath="$mainRepoDir/$outputFile" | ||
|
||
cd "$mainRepoDir" | ||
|
||
# Composer dev dependencies are huge. | ||
echo "Removing Composer dev dependencies..." | ||
composer --no-dev install > /dev/null 2>&1 | ||
|
||
# Remove previous zip file to prevent extra removed files to remain there | ||
if [[ -e "$zipFilePath" ]]; then | ||
rm "$zipFilePath" | ||
fi | ||
|
||
# Create the zip file in the current directory | ||
zip -r -y "$zipFilePath" "spec/" "src/" "vendor/" "config.xml" "LICENSE.md" "$pluginName.php" > /dev/null | ||
|
||
echo "Zip file created successfully." | ||
|
||
echo "Re-adding Composer dev dependencies..." | ||
composer install > /dev/null 2>&1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
FROM php:7.2-alpine | ||
|
||
ARG PLUGIN_SOURCE_DIR=/plugin-src | ||
ARG PLUGIN_VOLUME_DIR=/plugin | ||
|
||
ENV PLUGIN_SOURCE_DIR=$PLUGIN_SOURCE_DIR \ | ||
PLUGIN_VOLUME_DIR=$PLUGIN_VOLUME_DIR | ||
|
||
ENV LIMESURVEY_DB_HOST=mysql \ | ||
LIMESURVEY_DB_NAME=limesurvey \ | ||
LIMESURVEY_DB_USER=root \ | ||
LIMESURVEY_DB_PASSWORD='' \ | ||
LIMESURVEY_TABLE_PREFIX='' \ | ||
MYSQL_SSL_CA_CONTENTS='' | ||
|
||
RUN \ | ||
# TODO: Maybe get the Composer phar file ourselves? | ||
apk add composer && \ | ||
# To insert plugin data to plugins database | ||
docker-php-ext-install mysqli | ||
|
||
# Supposing the build context is the repo root, i.e. run it with -f when building | ||
COPY . "$PLUGIN_SOURCE_DIR" | ||
|
||
RUN mv "$PLUGIN_SOURCE_DIR/build-aux/docker/entrypoint.sh" /usr/bin | ||
|
||
RUN cd "$PLUGIN_SOURCE_DIR" && \ | ||
# Make sure to use PHP 7.2, not the one installed by APK (e.g. 7.3) | ||
/usr/local/bin/php /usr/bin/composer install --no-dev | ||
|
||
VOLUME ["$PLUGIN_VOLUME_DIR"] | ||
|
||
ENTRYPOINT ["entrypoint.sh"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#!/bin/sh | ||
|
||
# Exit on error | ||
set -eu | ||
|
||
insertPluginToDatabase() { | ||
"$PLUGIN_SOURCE_DIR"/build-aux/docker/wait-for "$LIMESURVEY_DB_HOST:3306" -t 30 -- \ | ||
echo "MySQL service detected!" && \ | ||
php "$PLUGIN_SOURCE_DIR"/build-aux/docker/register-plugin.php \ | ||
"$LIMESURVEY_DB_HOST" \ | ||
"$LIMESURVEY_DB_USER" \ | ||
"$LIMESURVEY_DB_PASSWORD" \ | ||
"$LIMESURVEY_DB_NAME" \ | ||
"$LIMESURVEY_TABLE_PREFIX" \ | ||
"$MYSQL_SSL_CA_CONTENTS" | ||
} | ||
|
||
main() { | ||
cp -a "$PLUGIN_SOURCE_DIR"/* "$PLUGIN_VOLUME_DIR" | ||
|
||
insertPluginToDatabase | ||
|
||
sleep infinity | ||
} | ||
|
||
main |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
<?php | ||
/** | ||
* Inserts the plugin record to the database. | ||
*/ | ||
|
||
function error(string $message) | ||
{ | ||
file_put_contents('php://stderr', $message . PHP_EOL, FILE_APPEND); | ||
exit(1); | ||
} | ||
|
||
function makeTempSslCaFile(string $contents) | ||
{ | ||
$file = tmpfile(); | ||
if ($file === false) { | ||
error('Cannot create temporary file to store MySQL SSL CA'); | ||
} | ||
|
||
fwrite($file, $contents); | ||
return $file; | ||
} | ||
|
||
function mysqlConnect(array $argv) | ||
{ | ||
$mysql = mysqli_init(); | ||
|
||
$sslCaFile = empty($argv[6]) ? null : makeTempSslCaFile($argv[6]); | ||
if ($sslCaFile !== null) { | ||
$mysql->ssl_set(null, null, stream_get_meta_data($sslCaFile)['uri'], null, null); | ||
} | ||
|
||
[$host, $socket] = explode(':', $argv[1], 2); | ||
$port = 0; | ||
if (is_numeric($socket)) { | ||
$port = (int) $socket; | ||
$socket = null; | ||
} | ||
|
||
$successful = $mysql->real_connect( | ||
$host, | ||
$argv[2], | ||
$argv[3], | ||
'', | ||
$port, | ||
$socket, | ||
MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT | ||
); | ||
|
||
if (!$successful) { | ||
error( | ||
"Cannot connect to MySQL: {$mysql->connect_error} " . | ||
"(error code {$mysql->connect_error})" | ||
); | ||
} | ||
|
||
return $mysql; | ||
} | ||
|
||
function isDatabaseExists(\mysqli $mysql, string $databaseName): bool | ||
{ | ||
$result = $mysql->query(<<<SQL | ||
SHOW DATABASES LIKE '$databaseName' | ||
SQL | ||
); | ||
|
||
return $result->num_rows === 1; | ||
} | ||
|
||
function makeTableName(string $tablePrefix): string | ||
{ | ||
if (!preg_match('/^[a-z0-9_$]*$/i', $tablePrefix)) { | ||
error('Table prefix contains invalid characters'); | ||
} | ||
|
||
return $tablePrefix . 'plugins'; | ||
} | ||
|
||
function isTableExists(\mysqli $mysql, string $tableName): bool | ||
{ | ||
$result = $mysql->query(<<<SQL | ||
SHOW TABLES LIKE '$tableName' | ||
SQL | ||
); | ||
|
||
return $result->num_rows === 1; | ||
} | ||
|
||
function isPluginAlreadyInserted(\mysqli $mysql, string $tableName): bool | ||
{ | ||
$result = $mysql->query(<<<SQL | ||
SELECT `id` FROM `$tableName` WHERE `name` = 'RestApi' | ||
SQL | ||
); | ||
|
||
return $result->num_rows > 0; | ||
} | ||
|
||
function insertPlugin(\mysqli $mysql, string $tableName): bool | ||
{ | ||
return $mysql->query(<<<SQL | ||
INSERT INTO `$tableName`(`name`, `plugin_type`, `active`) | ||
VALUES ('RestApi', 'upload', 1) | ||
SQL | ||
); | ||
} | ||
|
||
function main(array $argv) | ||
{ | ||
echo 'Registering the plugin...' . PHP_EOL; | ||
|
||
$mysql = mysqlConnect($argv); | ||
|
||
$databaseName = $mysql->real_escape_string($argv[4]); | ||
|
||
while (!isDatabaseExists($mysql, $databaseName)) { | ||
echo 'Waiting for the database to be created...' . PHP_EOL; | ||
sleep(3); | ||
} | ||
|
||
$mysql->select_db($databaseName); | ||
|
||
$pluginsTableName = makeTableName($argv[5]); | ||
|
||
while (!isTableExists($mysql, $pluginsTableName)) { | ||
echo "Waiting for the $pluginsTableName table to be created..." . PHP_EOL; | ||
sleep(3); | ||
} | ||
|
||
if (isPluginAlreadyInserted($mysql, $pluginsTableName)) { | ||
echo 'Plugin already registered, nothing to do.' . PHP_EOL; | ||
return; | ||
} | ||
|
||
if (!insertPlugin($mysql, $pluginsTableName)) { | ||
error("Cannot insert a new record to $pluginsTableName table!"); | ||
} | ||
|
||
echo 'Plugin registered and activated successfully...!' . PHP_EOL; | ||
} | ||
|
||
main($argv); |
Oops, something went wrong.