🎉 initial commit

This commit is contained in:
Marc Koch 2025-03-04 10:36:47 +01:00
commit c93a06972b
Signed by untrusted user who does not match committer: marc.koch
GPG key ID: 12406554CFB028B9
27 changed files with 4189 additions and 0 deletions

View file

@ -0,0 +1,146 @@
<?php
use CRM_Mailinglistsync_ExtensionUtil as E;
use Civi\Mailinglistsync\MailingListSettings as Settings;
/**
* Form controller class
*
* @see https://docs.civicrm.org/dev/en/latest/framework/quickform/
*/
class CRM_Mailinglistsync_Form_MailingListSettings extends CRM_Core_Form {
protected ?array $_settings = NULL;
public function buildQuickForm(): void {
$this->add(
'checkbox',
E::SHORT_NAME . '_enable',
label: E::ts('Enable synchronization of mailing lists groups and events'),
extra: ['class' => 'huge'],
);
$this->add(
'checkbox',
E::SHORT_NAME . '_logging',
label: E::ts('Enable logging of synchronization'),
extra: ['class' => 'huge'],
);
$this->add(
'text',
E::SHORT_NAME . '_mlmmj_host',
label: E::ts('mlmmj Host'),
extra: ['class' => 'huge'],
);
$this->add(
'password',
E::SHORT_NAME . '_mlmmj_token',
label: E::ts('mlmmj Token'),
extra: ['class' => 'huge'],
);
$this->add(
'text',
E::SHORT_NAME . '_mlmmj_port',
label: E::ts('mlmmj Port<br>(default: 443)'),
extra: ['class' => 'huge'],
);
$this->add(
'text',
E::SHORT_NAME . '_dovecot_host',
label: E::ts('Dovecot Host'),
extra: ['class' => 'huge'],
);
$this->add(
'password',
E::SHORT_NAME . '_dovecot_token',
label: E::ts('Dovecot Token'),
extra: ['class' => 'huge'],
);
$this->add(
'text',
E::SHORT_NAME . '_dovecot_port',
label: E::ts('Dovecot Port<br>(default: 443)'),
extra: ['class' => 'huge'],
);
$this->add(
'select',
E::SHORT_NAME . '_participant_status',
label: E::ts('Participant status'),
attributes: static::getParticipantStatusOptions(),
extra: ['class' => 'crm-select2 huge', 'multiple' => 'multiple']
);
$this->add(
'select',
E::SHORT_NAME . '_ad_contact_tags',
label: E::ts('Tags to restrict contact matching for AD groups'),
attributes: static::getContactTags(),
extra: ['class' => 'crm-select2 huge', 'multiple' => 'multiple']
);
$this->addButtons([
[
'type' => 'submit',
'name' => E::ts('Submit'),
'isDefault' => TRUE,
],
]);
$this->assign('EXTENSION_SHORT_NAME', E::SHORT_NAME);
parent::buildQuickForm();
}
public function setDefaultValues() {
return Settings::get();
}
public function postProcess(): void {
// Set configuration values
Settings::set($this->exportValues());
parent::postProcess();
// Display message
CRM_Utils_System::setUFMessage(E::ts('Settings saved'));
}
public function validate(): bool {
parent::validate();
Settings::validate($this->exportValues(), $this->_errors);
return (0 == count($this->_errors));
}
/**
* Get the participant status options.
*
* @return array
*
* @throws \Civi\API\Exception\UnauthorizedException
* @throws \CRM_Core_Exception
*/
protected static function getParticipantStatusOptions(): array {
$result = \Civi\Api4\ParticipantStatusType::get()
->addSelect('id', 'label')
->addWhere('is_active', '=', TRUE)
->execute()
->getArrayCopy();
return array_column($result, 'label', 'id');
}
/**
* Get available contact tags.
*
* @return array
*
* @throws \CRM_Core_Exception
* @throws \Civi\API\Exception\UnauthorizedException
*/
protected static function getContactTags(): array {
$result = \Civi\Api4\Tag::get()
->addSelect('id', 'label')
->addWhere('used_for', '=', 'civicrm_contact')
->addWhere('is_selectable', '=', TRUE)
->addWhere('is_tagset', '=', FALSE)
->execute()
->getArrayCopy();
return array_column($result, 'label', 'id');
}
}

View file

@ -0,0 +1,180 @@
<?php
use Civi\Api4\CustomGroup;
use CRM_Mailinglistsync_ExtensionUtil as E;
/**
* Custom groups to enable/disable on extension enable/disable.
*/
const MAILINGLISTSYNC_CUSTOM_GROUPS = ['Group_Mailing_List', 'Event_Mailing_List'];
/**
* Collection of upgrade steps.
*/
class CRM_Mailinglistsync_Upgrader extends \CRM_Extension_Upgrader_Base {
/**
* On install, create new location types.
*
* @throws \CRM_Core_Exception
*/
public function install(): void {
// Create a new location types
$locationTypes = require_once E::path() . '/resources/location_types.php';
foreach ($locationTypes as $location) {
try {
\Civi\Api4\LocationType::create(FALSE)
->addValue('name', $location['name'])
->addValue('display_name', $location['display_name'])
->addValue('description', $location['description'])
->addValue('is_default', $location['is_default'])
->execute();
// $this->ctx->log->info(E::ts('Created %1 LocationType', [1 => $location['name']]));
}
catch (\CRM_Core_Exception $e) {
if ($e->getMessage() == 'DB Error: already exists') {
// $this->ctx->log->info(E::ts('LocationType %1 already exists', [1 => $location['name']]));
continue;
}
// $this->ctx->log->err(E::ts('Failed to create %1 LocationType', [1 => $location['name']]));
throw $e;
}
}
}
/**
* Example: Work with entities usually not available during the install step.
*
* This method can be used for any post-install tasks. For example, if a step
* of your installation depends on accessing an entity that is itself
* created during the installation (e.g., a setting or a managed entity), do
* so here to avoid order of operation problems.
*/
// public function postInstall(): void {
// $customFieldId = civicrm_api3('CustomField', 'getvalue', array(
// 'return' => array("id"),
// 'name' => "customFieldCreatedViaManagedHook",
// ));
// civicrm_api3('Setting', 'create', array(
// 'myWeirdFieldSetting' => array('id' => $customFieldId, 'weirdness' => 1),
// ));
// }
/**
* Example: Run an external SQL script when the module is uninstalled.
*
* Note that if a file is present sql\auto_uninstall that will run regardless
* of this hook.
*/
// public function uninstall(): void {
// $this->executeSqlFile('sql/my_uninstall.sql');
// }
/**
* Runs when enabling the extension.
*
* @throws \CRM_Core_Exception
*/
public function enable(): void {
// Enable CustomGroups
foreach (MAILINGLISTSYNC_CUSTOM_GROUPS as $customGroup) {
CustomGroup::update(FALSE)
->addWhere('name', '=', $customGroup)
->addValue('is_active', 1)
->execute();
// $this->ctx->log->info(E::ts('Enabled %1 CustomGroup', [1 => $customGroup]));
}
}
/**
* Runs when disabling the extension.
*
* @throws \CRM_Core_Exception
*/
public function disable(): void {
// Disable CustomGroups
foreach (MAILINGLISTSYNC_CUSTOM_GROUPS as $customGroup) {
CustomGroup::update(FALSE)
->addWhere('name', '=', $customGroup)
->addValue('is_active', 0)
->execute();
// $this->ctx->log->info(E::ts('Disabled %1 CustomGroup', [1 => $customGroup]));
}
}
/**
* Example: Run a couple simple queries.
*
* @return TRUE on success
* @throws CRM_Core_Exception
*/
// public function upgrade_4200(): bool {
// $this->ctx->log->info('Applying update 4200');
// CRM_Core_DAO::executeQuery('UPDATE foo SET bar = "whiz"');
// CRM_Core_DAO::executeQuery('DELETE FROM bang WHERE willy = wonka(2)');
// return TRUE;
// }
/**
* Example: Run an external SQL script.
*
* @return TRUE on success
* @throws CRM_Core_Exception
*/
// public function upgrade_4201(): bool {
// $this->ctx->log->info('Applying update 4201');
// // this path is relative to the extension base dir
// $this->executeSqlFile('sql/upgrade_4201.sql');
// return TRUE;
// }
/**
* Example: Run a slow upgrade process by breaking it up into smaller chunk.
*
* @return TRUE on success
* @throws CRM_Core_Exception
*/
// public function upgrade_4202(): bool {
// $this->ctx->log->info('Planning update 4202'); // PEAR Log interface
// $this->addTask(E::ts('Process first step'), 'processPart1', $arg1, $arg2);
// $this->addTask(E::ts('Process second step'), 'processPart2', $arg3, $arg4);
// $this->addTask(E::ts('Process second step'), 'processPart3', $arg5);
// return TRUE;
// }
// public function processPart1($arg1, $arg2) { sleep(10); return TRUE; }
// public function processPart2($arg3, $arg4) { sleep(10); return TRUE; }
// public function processPart3($arg5) { sleep(10); return TRUE; }
/**
* Example: Run an upgrade with a query that touches many (potentially
* millions) of records by breaking it up into smaller chunks.
*
* @return TRUE on success
* @throws CRM_Core_Exception
*/
// public function upgrade_4203(): bool {
// $this->ctx->log->info('Planning update 4203'); // PEAR Log interface
// $minId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(min(id),0) FROM civicrm_contribution');
// $maxId = CRM_Core_DAO::singleValueQuery('SELECT coalesce(max(id),0) FROM civicrm_contribution');
// for ($startId = $minId; $startId <= $maxId; $startId += self::BATCH_SIZE) {
// $endId = $startId + self::BATCH_SIZE - 1;
// $title = E::ts('Upgrade Batch (%1 => %2)', array(
// 1 => $startId,
// 2 => $endId,
// ));
// $sql = '
// UPDATE civicrm_contribution SET foobar = apple(banana()+durian)
// WHERE id BETWEEN %1 and %2
// ';
// $params = array(
// 1 => array($startId, 'Integer'),
// 2 => array($endId, 'Integer'),
// );
// $this->addTask($title, 'executeSql', $sql, $params);
// }
// return TRUE;
// }
}