Skip to content

Commit

Permalink
Initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
Massi-X committed Feb 3, 2024
0 parents commit 344426f
Show file tree
Hide file tree
Showing 30 changed files with 5,382 additions and 0 deletions.
38 changes: 38 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.
10 changes: 10 additions & 0 deletions .github/ISSUE_TEMPLATE/custom.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''

---


20 changes: 20 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.
174 changes: 174 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
# VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
*.code-workspace
# Local History for Visual Studio Code
.history/

# Common credential files
**/credentials.json
**/client_secrets.json
**/client_secret.json
*creds*
*.dat
*password*
*.httr-oauth*

# Private Node Modules
node_modules/
creds.js

# Private Files
*.json
*.csv
*.csv.gz
*.tsv
*.tsv.gz
*.xlsx


# Mac/OSX
.DS_Store


# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
# Usually these files are written by a <a href="https://www.jcchouinard.com/learn-python/">python</a> script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
.pybuilder/
target/

# <a href="https://www.jcchouinard.com/how-to-use-jupyter-notebook/">Jupyter Notebook</a>
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version

# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in <a href="https://www.jcchouinard.com/git/">version control</a>.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# <a href="https://www.jcchouinard.com/python-with-spyder-ide/">Spyder</a> project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/

# Cython debug symbols
cython_debug/
23 changes: 23 additions & 0 deletions Backup.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php
/*
* CardDAV Middleware UI
* Written by Massi-X <[email protected]> © 2023
* This file is protected under CC-BY-NC-ND-4.0, please see "LICENSE" file for more information
*/

namespace FreePBX\modules\PhoneMiddleware;

use FreePBX\modules\Backup as Base;

class Backup extends Base\BackupBase
{
public function runBackup($id, $transaction)
{
$Core = $this->FreePBX->PhoneMiddleware->getCore(); //get instance beacuse I cannot access statically here

if (method_exists($Core, 'run_backup')) {
$Core->run_backup($this);
} else
throw new \Exception(_('Backup is not implemented!'));
}
}
118 changes: 118 additions & 0 deletions CoreInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php
/*
* CardDAV Middleware UI
* Written by Massi-X <[email protected]> © 2023
* This file is protected under CC-BY-NC-ND-4.0, please see "LICENSE" file for more information
*/

/******************************************************************************/
/*** These are the methods to implement to create a working Core class ***/
/******************************************************************************/

interface CoreInterface
{
public static function getInstance(): self; //return a Core instance
public function init(): void; //initialize anything you might need to

//getter and setter for various parameters settable in UI. BMO class will get the values and pass them back through these methods. Any logic should be implemented at your wish.
public static function get_url(): string; //server url
public static function set_url(string $url): void;
public static function get_carddav_addressbooks(): array; //addressbooks URIs
public static function set_carddav_addressbooks(array $carddav_addressbooks): void;
public static function get_auth(): array; //carddav auth info
public static function set_auth(string $username, string $password): void;
public static function get_cache_expire(): int; //cache duration
public static function set_cache_expire(int $expire): void;
public static function get_country_code(): string; //country code
public static function set_country_code(string $code): void;
public static function get_output_construct(): string; //format of the CNAM output
public static function set_output_construct(string $output_construct): void;
public static function get_max_cnam_length(): int; //CNAM max allowed length
public static function set_max_cnam_length(int $max_cnam_length): void;
public static function get_phone_type(): int; //user device type
public static function set_phone_type(int $phone_type): void;
public static function get_mail_level(): array; //importance level when notifications will be sent also via mail
public static function set_mail_level(array $types): void;
public static function get_superfecta_compat(): bool; //superfecta compatibility switch
public static function set_superfecta_compat(bool $superfecta_compat): void;
public static function get_spam_match(): bool; //spam match report
public static function set_spam_match(bool $spam_match): void;

public function store_config(): bool; //called when the UI class wants to store the data (i.e. when the user clicks "Apply")
public static function delete_cache(): bool; //if you have any cache, this method is called to invalidate it if there is any breaking change.

public function getXMLforPhones(bool $force = false): string; //returns a well formatted xml phonebook that can be read by a phone/other device. $force to force refresh
public function getCNFromPhone(string $number, bool $force = false); //returns a CNAM (name) given a phone number. You should really not use $force because the result must come as fast as possible - output type should be string|null (not supported in PHP7)

public function discover_addressbooks_to_display(): array; //returns an array of addressbooks based on the current url, username and password. This s used by the UI in conjunction with get_carddav_addressbooks() to create a list of the current active/inactive addressbooks.
public static function sendUINotification(int $type, string $message, int $id, int $flags): void; //send a notification that will be displayed in the top right corner of the UI. $type = the type (see constants below), $message = the text of the notification, $id = unique id, $flags = flags (see constants below).
public static function retrieveUINotifications(): array; //retrieve an array of UI notifications so that UI can display it
public static function deleteUINotification(int $id): bool; //delete a notification by ID
public static function deleteAllUINotifications(): bool; //delete all the notifications

/******************************************************************************/
/*** Do not modify/delete constants! ***/
/******************************************************************************/

//if new are added remember to update getXMLforPhones + BMO class with new languages. MUST BE CONSECUTIVE. MUST START AT 1 (NOT 0).
public const PHONE_TYPE_NO_LIMITS = 1;
public const PHONE_TYPE_FANVIL = 2;
public const PHONE_TYPE_SNOM = 3;
public const PHONE_TYPES = [self::PHONE_TYPE_NO_LIMITS, self::PHONE_TYPE_FANVIL, self::PHONE_TYPE_SNOM];

//notification type and options constants. You can put below fixed notification IDs (> 0 && < 1000)
public const NOTIFICATION_TYPE_VERBOSE = 1; //this is a verbose message
public const NOTIFICATION_TYPE_ERROR = 2; //this is an error message
public const NOTIFICATION_TYPE_INFO = 3; //this is an info message
public const NOTIFICATION_FLAG_NO_MAIL = 0b0001; //overwrite mail send if needed
}

/******************************************************************************/
/*** These are optional methods of your Core class ***/
/******************************************************************************/

interface UIAddons
{
public static function get_module_name(): string; //return here your module name to be displayed in UI
public static function get_author(): string; //return here your name to be displayed in UI
public static function get_readme_url(): string; //return here your readme URL if you have one. Must be a valid HTML <a href=...>
public static function get_license_to_display(): array; //if you have a license, you should have this method too. returns ['description' => intestation with '%linkstart' and '%Linkend' anchors to be replaced for license link, 'text' => full text of the license, 'title' => title of the dialog]
public static function get_libraries_to_display(): array; //any library you used. returns array of arrays containing ['name' => library name, 'url' => library url]
public static function get_additional_footer(): string; //any additional information to print in footer
public static function get_help(): array; //return an array of raw strings containing help informations to print for the user. You should use the sandard format: <b>title:</b>text...
}

interface Activation
{
public static function get_purchase_buttons(): string; //return a well formatted HTML string containing your purchase/donation button(s). Include any <script> or <style> you want to use here. You can take advantage of the ajax calls createorder (that will call create_order()), validatepurchase (validate_purchase()) and restorepurchase (restore_purchase())
/**
* @throws Exception in case of errors
*/
public static function create_order(): array; //this function is called by ajax. Return array formatted like ["result" => true/false, "message" => ...]
/**
* @throws Exception in case of errors
*/
public static function validate_purchase(array $POST, string $php_input): array; //this function is called by ajax and gives you the $_POST array and php_input data (if any). Return array formatted like ["result" => true/false, "message" => ...]
/**
* @throws Exception in case of errors
*/
public static function restore_purchase(array $POST, string $php_input): array; //this function is called by ajax and gives you the $_POST array and php_input data (if any). Return array formatted like ["result" => true/false, "message" => ...]
}


interface InstallUninstall
{
public static function post_install_hook(\FreePBX $FreePBX): void; //hooks to be executed on module install. NB! Do not throw Exceptions if not necessary or the installation will fail!
public static function post_uninstall_hook(\FreePBX $FreePBX): void; //hooks to be executed on module uninstall. Any thrown exception will be catched and a warning will be printed. Uninstallation will succeed anyway
}

interface BackupRestore
{
public static function run_backup(object $backupInstance): void; //place here your code to be executed when the user request a backup. instance is the backup instance, see https://wiki.freepbx.org/display/FOP/Implementing+Backup for the methods
public static function run_restore(object $restoreInstance, string $version): void; //place here your code to be executed when the user request a restore. instance is the restore instance, see https://wiki.freepbx.org/display/FOP/Implementing+Backup for the methods
}

interface Scheduler
{
public static function run_job(\FreePBX $FreePBX, Symfony\Component\Console\Input\InputInterface $input, Symfony\Component\Console\Output\OutputInterface $output): bool; //run a periodic Job automatically. This method is called every minute and you must implement a logic to prevent it from running over and over again. $FreePBX = BMO object, $input = Symfony InputInterface, $output = Symfony OutputInterface
}
Loading

0 comments on commit 344426f

Please sign in to comment.