diff --git a/CRM/TwingleCampaign/BAO/TwingleEvent.php b/CRM/TwingleCampaign/BAO/TwingleEvent.php index faf609b..4248c1d 100644 --- a/CRM/TwingleCampaign/BAO/TwingleEvent.php +++ b/CRM/TwingleCampaign/BAO/TwingleEvent.php @@ -219,15 +219,13 @@ class CRM_TwingleCampaign_BAO_TwingleEvent extends Campaign { private static function matchContact(string $names, string $email): ?int { $names = StringOps::split_names($names); // Hopefully just a temporary solution - $firstnames = $names['firstnames'] ?? NULL; - $lastname = $names['lastname'] ?? NULL; - $display_name = $names['display_name'] ?? NULL; + $firstnames = $names['firstnames']; + $lastname = $names['lastname']; try { $contact = civicrm_api3('Contact', 'getorcreate', [ 'xcm_profile' => Civi::settings()->get('twinglecampaign_xcm_profile'), 'first_name' => $firstnames, 'last_name' => $lastname, - 'display_name' => $display_name, 'email' => $email, ]); return (int) $contact['id']; diff --git a/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php index 61baf6b..0f99555 100644 --- a/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php +++ b/CRM/TwingleCampaign/Exceptions/TwingleCampaignException.php @@ -1,8 +1,8 @@ $e->getMessage()] ), E::ts('Scheduled Job'), - 'error' + error ); } diff --git a/CRM/TwingleCampaign/Upgrader/Base.php b/CRM/TwingleCampaign/Upgrader/Base.php new file mode 100644 index 0000000..c5e6ef0 --- /dev/null +++ b/CRM/TwingleCampaign/Upgrader/Base.php @@ -0,0 +1,376 @@ +ctx = array_shift($args); + $instance->queue = $instance->ctx->queue; + $method = array_shift($args); + return call_user_func_array(array($instance, $method), $args); + } + + public function __construct($extensionName, $extensionDir) { + $this->extensionName = $extensionName; + $this->extensionDir = $extensionDir; + } + + // ******** Task helpers ******** + + /** + * Run a CustomData file. + * + * @param string $relativePath the CustomData XML file path (relative to this extension's dir) + * @return bool + */ + public function executeCustomDataFile($relativePath) { + $xml_file = $this->extensionDir . '/' . $relativePath; + return $this->executeCustomDataFileByAbsPath($xml_file); + } + + /** + * Run a CustomData file + * + * @param string $xml_file the CustomData XML file path (absolute path) + * + * @return bool + */ + protected static function executeCustomDataFileByAbsPath($xml_file) { + $import = new CRM_Utils_Migrate_Import(); + $import->run($xml_file); + return TRUE; + } + + /** + * Run a SQL file. + * + * @param string $relativePath the SQL file path (relative to this extension's dir) + * + * @return bool + */ + public function executeSqlFile($relativePath) { + CRM_Utils_File::sourceSQLFile( + CIVICRM_DSN, + $this->extensionDir . DIRECTORY_SEPARATOR . $relativePath + ); + return TRUE; + } + + /** + * @param string $tplFile + * The SQL file path (relative to this extension's dir). + * Ex: "sql/mydata.mysql.tpl". + * @return bool + */ + public function executeSqlTemplate($tplFile) { + // Assign multilingual variable to Smarty. + $upgrade = new CRM_Upgrade_Form(); + + $tplFile = CRM_Utils_File::isAbsolute($tplFile) ? $tplFile : $this->extensionDir . DIRECTORY_SEPARATOR . $tplFile; + $smarty = CRM_Core_Smarty::singleton(); + $smarty->assign('domainID', CRM_Core_Config::domainID()); + CRM_Utils_File::sourceSQLFile( + CIVICRM_DSN, $smarty->fetch($tplFile), NULL, TRUE + ); + return TRUE; + } + + /** + * Run one SQL query. + * + * This is just a wrapper for CRM_Core_DAO::executeSql, but it + * provides syntatic sugar for queueing several tasks that + * run different queries + */ + public function executeSql($query, $params = array()) { + // FIXME verify that we raise an exception on error + CRM_Core_DAO::executeQuery($query, $params); + return TRUE; + } + + /** + * Syntatic sugar for enqueuing a task which calls a function in this class. + * + * The task is weighted so that it is processed + * as part of the currently-pending revision. + * + * After passing the $funcName, you can also pass parameters that will go to + * the function. Note that all params must be serializable. + */ + public function addTask($title) { + $args = func_get_args(); + $title = array_shift($args); + $task = new CRM_Queue_Task( + array(get_class($this), '_queueAdapter'), + $args, + $title + ); + return $this->queue->createItem($task, array('weight' => -1)); + } + + // ******** Revision-tracking helpers ******** + + /** + * Determine if there are any pending revisions. + * + * @return bool + */ + public function hasPendingRevisions() { + $revisions = $this->getRevisions(); + $currentRevision = $this->getCurrentRevision(); + + if (empty($revisions)) { + return FALSE; + } + if (empty($currentRevision)) { + return TRUE; + } + + return ($currentRevision < max($revisions)); + } + + /** + * Add any pending revisions to the queue. + */ + public function enqueuePendingRevisions(CRM_Queue_Queue $queue) { + $this->queue = $queue; + + $currentRevision = $this->getCurrentRevision(); + foreach ($this->getRevisions() as $revision) { + if ($revision > $currentRevision) { + $title = ts('Upgrade %1 to revision %2', array( + 1 => $this->extensionName, + 2 => $revision, + )); + + // note: don't use addTask() because it sets weight=-1 + + $task = new CRM_Queue_Task( + array(get_class($this), '_queueAdapter'), + array('upgrade_' . $revision), + $title + ); + $this->queue->createItem($task); + + $task = new CRM_Queue_Task( + array(get_class($this), '_queueAdapter'), + array('setCurrentRevision', $revision), + $title + ); + $this->queue->createItem($task); + } + } + } + + /** + * Get a list of revisions. + * + * @return array(revisionNumbers) sorted numerically + */ + public function getRevisions() { + if (!is_array($this->revisions)) { + $this->revisions = array(); + + $clazz = new ReflectionClass(get_class($this)); + $methods = $clazz->getMethods(); + foreach ($methods as $method) { + if (preg_match('/^upgrade_(.*)/', $method->name, $matches)) { + $this->revisions[] = $matches[1]; + } + } + sort($this->revisions, SORT_NUMERIC); + } + + return $this->revisions; + } + + public function getCurrentRevision() { + $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName); + if (!$revision) { + $revision = $this->getCurrentRevisionDeprecated(); + } + return $revision; + } + + private function getCurrentRevisionDeprecated() { + $key = $this->extensionName . ':version'; + if ($revision = CRM_Core_BAO_Setting::getItem('Extension', $key)) { + $this->revisionStorageIsDeprecated = TRUE; + } + return $revision; + } + + public function setCurrentRevision($revision) { + CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision); + // clean up legacy schema version store (CRM-19252) + $this->deleteDeprecatedRevision(); + return TRUE; + } + + private function deleteDeprecatedRevision() { + if ($this->revisionStorageIsDeprecated) { + $setting = new CRM_Core_BAO_Setting(); + $setting->name = $this->extensionName . ':version'; + $setting->delete(); + CRM_Core_Error::debug_log_message("Migrated extension schema revision ID for {$this->extensionName} from civicrm_setting (deprecated) to civicrm_extension.\n"); + } + } + + // ******** Hook delegates ******** + + /** + * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_install + */ + public function onInstall() { + $files = glob($this->extensionDir . '/sql/*_install.sql'); + if (is_array($files)) { + foreach ($files as $file) { + CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); + } + } + $files = glob($this->extensionDir . '/sql/*_install.mysql.tpl'); + if (is_array($files)) { + foreach ($files as $file) { + $this->executeSqlTemplate($file); + } + } + $files = glob($this->extensionDir . '/xml/*_install.xml'); + if (is_array($files)) { + foreach ($files as $file) { + $this->executeCustomDataFileByAbsPath($file); + } + } + if (is_callable(array($this, 'install'))) { + $this->install(); + } + } + + /** + * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall + */ + public function onPostInstall() { + $revisions = $this->getRevisions(); + if (!empty($revisions)) { + $this->setCurrentRevision(max($revisions)); + } + if (is_callable(array($this, 'postInstall'))) { + $this->postInstall(); + } + } + + /** + * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall + */ + public function onUninstall() { + $files = glob($this->extensionDir . '/sql/*_uninstall.mysql.tpl'); + if (is_array($files)) { + foreach ($files as $file) { + $this->executeSqlTemplate($file); + } + } + if (is_callable(array($this, 'uninstall'))) { + $this->uninstall(); + } + $files = glob($this->extensionDir . '/sql/*_uninstall.sql'); + if (is_array($files)) { + foreach ($files as $file) { + CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); + } + } + } + + /** + * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_enable + */ + public function onEnable() { + // stub for possible future use + if (is_callable(array($this, 'enable'))) { + $this->enable(); + } + } + + /** + * @see https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable + */ + public function onDisable() { + // stub for possible future use + if (is_callable(array($this, 'disable'))) { + $this->disable(); + } + } + + public function onUpgrade($op, CRM_Queue_Queue $queue = NULL) { + switch ($op) { + case 'check': + return array($this->hasPendingRevisions()); + + case 'enqueue': + return $this->enqueuePendingRevisions($queue); + + default: + } + } + +} diff --git a/CRM/TwingleCampaign/Utils/APIWrapper.php b/CRM/TwingleCampaign/Utils/APIWrapper.php index 06ff396..5afe426 100644 --- a/CRM/TwingleCampaign/Utils/APIWrapper.php +++ b/CRM/TwingleCampaign/Utils/APIWrapper.php @@ -40,8 +40,8 @@ class CRM_TwingleCampaign_Utils_APIWrapper { $response_copy = $response; // Create soft credit for contribution - if (array_key_exists('contribution', $response)) { - $contribution = array_shift($response_copy['contribution']); + if (array_key_exists('contribution', $response['values'])) { + $contribution = array_shift($response_copy['values']['contribution']); if (array_key_exists('campaign_id', $contribution)) { try { $twingle_event = civicrm_api3( @@ -49,7 +49,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper { 'getsingle', ['id' => $contribution['campaign_id']] ); - $response['soft_credit'] = + $response['values']['soft_credit'] = self::createSoftCredit($contribution, $twingle_event)['values']; $event->setResponse($response); } catch (CiviCRM_API3_Exception $e) { @@ -58,8 +58,8 @@ class CRM_TwingleCampaign_Utils_APIWrapper { } } // Create soft credit for sepa mandate - elseif (array_key_exists('sepa_mandate', $response)) { - $sepa_mandate = array_pop($response_copy['sepa_mandate']); + elseif (array_key_exists('sepa_mandate', $response['values'])) { + $sepa_mandate = array_pop($response_copy['values']['sepa_mandate']); try { $contribution = civicrm_api3( @@ -84,7 +84,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper { 'getsingle', ['id' => $contribution['contribution_campaign_id']] ); - $response['soft_credit'] = + $response['values']['soft_credit'] = self::createSoftCredit($contribution, $twingle_event)['values']; $event->setResponse($response); } catch (CiviCRM_API3_Exception $e) { @@ -103,12 +103,12 @@ class CRM_TwingleCampaign_Utils_APIWrapper { * the de.systopia.twingle extension can include the campaign into the * contribution which it will create. * - * @param array $apiRequest - * @param callable $callsame + * @param $apiRequest + * @param $callsame * * @return mixed */ - public static function mapDonation(array $apiRequest, callable $callsame) { + public function mapDonation($apiRequest, $callsame) { if (array_key_exists( 'campaign_id', @@ -129,7 +129,11 @@ class CRM_TwingleCampaign_Utils_APIWrapper { } } } - elseif (!empty($apiRequest['params']['custom_fields']['event'])) { + elseif (array_key_exists( + 'event', + $apiRequest['params']['custom_fields']) && + !empty($apiRequest['params']['custom_fields']['event']) + ) { try { $targetCampaign = civicrm_api3( 'TwingleEvent', @@ -200,9 +204,7 @@ class CRM_TwingleCampaign_Utils_APIWrapper { 'contribution_id' => $contribution['id'], ] ); - - throw $e; } } -} +} \ No newline at end of file diff --git a/CRM/TwingleCampaign/Utils/StringOperations.php b/CRM/TwingleCampaign/Utils/StringOperations.php index 98e6657..19c0fd3 100644 --- a/CRM/TwingleCampaign/Utils/StringOperations.php +++ b/CRM/TwingleCampaign/Utils/StringOperations.php @@ -49,7 +49,7 @@ class CRM_TwingleCampaign_Utils_StringOperations { $firstnames = implode(" ", $names); return ['firstnames' => $firstnames, 'lastname' => $lastname]; } - return ['display_name' => $string]; + return $string; } /** @@ -71,4 +71,4 @@ class CRM_TwingleCampaign_Utils_StringOperations { public static function startsWith($haystack, $needle): bool { return substr_compare($haystack, $needle, 0, strlen($needle)) === 0; } -} +} \ No newline at end of file diff --git a/api/v3/TwingleProject/Sync.php b/api/v3/TwingleProject/Sync.php index ca72d0e..aed3d2a 100644 --- a/api/v3/TwingleProject/Sync.php +++ b/api/v3/TwingleProject/Sync.php @@ -193,8 +193,8 @@ function civicrm_api3_twingle_project_Sync(array $params): array { foreach ($projects_from_civicrm['values'] as $project_from_civicrm) { if ( !in_array($project_from_civicrm['project_id'], - array_column($projects_from_twingle, 'id'), - ) && $project_from_civicrm['is_active'] == 1) { + array_column($projects_from_twingle, 'id') + )) { // store campaign id in $id $id = $project_from_civicrm['id']; unset($project_from_civicrm['id']); diff --git a/info.xml b/info.xml index c94db40..5c2e000 100644 --- a/info.xml +++ b/info.xml @@ -5,23 +5,25 @@ Manage Twingle projects and events as campaigns in CiviCRM AGPL-3.0 - Marc Koch - marc.koch@propeace.de + Marc Michalsky + michalsky@forumzfd.de - https://lab.civicrm.org/Marc_Koch/de-forumzfd-twinglecampaign - https://lab.civicrm.org/Marc_Koch/de-forumzfd-twinglecampaign - https://lab.civicrm.org/Marc_Koch/de-forumzfd-twinglecampaign/-/issues + https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign + https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign + https://lab.civicrm.org/Marc_Michalsky/de-forumzfd-twinglecampaign/-/issues http://www.gnu.org/licenses/agpl-3.0.html - 2024-06-15 - 1.1.0-beta - beta + 2023-02-28 + 1.0.5 + stable - 5.74 + 5.14.0 + de.systopia.xcm + de.systopia.campaign de.systopia.twingle @@ -30,11 +32,9 @@ CRM/TwingleCampaign - 24.09.1 + 22.10.0 menu-xml@1.0.0 - smarty@1.0.3 - CRM_TwingleCampaign_Upgrader diff --git a/mixin/lib/civimix-schema@5.78.beta1.phar b/mixin/lib/civimix-schema@5.78.beta1.phar deleted file mode 100644 index 079ec36..0000000 Binary files a/mixin/lib/civimix-schema@5.78.beta1.phar and /dev/null differ diff --git a/mixin/menu-xml@1.0.0.mixin.php b/mixin/menu-xml@1.0.0.mixin.php new file mode 100644 index 0000000..4c0b227 --- /dev/null +++ b/mixin/menu-xml@1.0.0.mixin.php @@ -0,0 +1,31 @@ +addListener('hook_civicrm_xmlMenu', function ($e) use ($mixInfo) { + if (!$mixInfo->isActive()) { + return; + } + + $files = (array) glob($mixInfo->getPath('xml/Menu/*.xml')); + foreach ($files as $file) { + $e->files[] = $file; + } + }); + +}; diff --git a/mixin/polyfill.php b/mixin/polyfill.php new file mode 100644 index 0000000..f57c5eb --- /dev/null +++ b/mixin/polyfill.php @@ -0,0 +1,101 @@ +')) { + $mixinVers[$name] = $ver; + } + } + $mixins = []; + foreach ($mixinVers as $name => $ver) { + $mixins[] = "$name@$ver"; + } + + // Imitate CRM_Extension_MixInfo. + $mixInfo = new class() { + + /** + * @var string + */ + public $longName; + + /** + * @var string + */ + public $shortName; + + public $_basePath; + + public function getPath($file = NULL) { + return $this->_basePath . ($file === NULL ? '' : (DIRECTORY_SEPARATOR . $file)); + } + + public function isActive() { + return \CRM_Extension_System::singleton()->getMapper()->isActiveModule($this->shortName); + } + + }; + $mixInfo->longName = $longName; + $mixInfo->shortName = $shortName; + $mixInfo->_basePath = $basePath; + + // Imitate CRM_Extension_BootCache. + $bootCache = new class() { + + public function define($name, $callback) { + $envId = \CRM_Core_Config_Runtime::getId(); + $oldExtCachePath = \Civi::paths()->getPath("[civicrm.compile]/CachedExtLoader.{$envId}.php"); + $stat = stat($oldExtCachePath); + $file = Civi::paths()->getPath('[civicrm.compile]/CachedMixin.' . md5($name . ($stat['mtime'] ?? 0)) . '.php'); + if (file_exists($file)) { + return include $file; + } + else { + $data = $callback(); + file_put_contents($file, '<' . "?php\nreturn " . var_export($data, 1) . ';'); + return $data; + } + } + + }; + + // Imitate CRM_Extension_MixinLoader::run() + // Parse all live mixins before trying to scan any classes. + global $_CIVIX_MIXIN_POLYFILL; + foreach ($mixins as $mixin) { + // If the exact same mixin is defined by multiple exts, just use the first one. + if (!isset($_CIVIX_MIXIN_POLYFILL[$mixin])) { + $_CIVIX_MIXIN_POLYFILL[$mixin] = include_once $basePath . '/mixin/' . $mixin . '.mixin.php'; + } + } + foreach ($mixins as $mixin) { + // If there's trickery about installs/uninstalls/resets, then we may need to register a second time. + if (!isset(\Civi::$statics[__FUNCTION__][$mixin])) { + \Civi::$statics[__FUNCTION__][$mixin] = 1; + $func = $_CIVIX_MIXIN_POLYFILL[$mixin]; + $func($mixInfo, $bootCache); + } + } +}; diff --git a/twinglecampaign.civix.php b/twinglecampaign.civix.php index 31e9480..f9ec727 100644 --- a/twinglecampaign.civix.php +++ b/twinglecampaign.civix.php @@ -75,43 +75,14 @@ class CRM_TwingleCampaign_ExtensionUtil { return self::CLASS_PREFIX . '_' . str_replace('\\', '_', $suffix); } - /** - * @return \CiviMix\Schema\SchemaHelperInterface - */ - public static function schema() { - if (!isset($GLOBALS['CiviMixSchema'])) { - pathload()->loadPackage('civimix-schema@5', TRUE); - } - return $GLOBALS['CiviMixSchema']->getHelper(static::LONG_NAME); - } - } use CRM_TwingleCampaign_ExtensionUtil as E; -pathload()->addSearchDir(__DIR__ . '/mixin/lib'); -spl_autoload_register('_twinglecampaign_civix_class_loader', TRUE, TRUE); - -function _twinglecampaign_civix_class_loader($class) { - if ($class === 'CRM_TwingleCampaign_DAO_Base') { - if (version_compare(CRM_Utils_System::version(), '5.74.beta', '>=')) { - class_alias('CRM_Core_DAO_Base', 'CRM_TwingleCampaign_DAO_Base'); - // ^^ Materialize concrete names -- encourage IDE's to pick up on this association. - } - else { - $realClass = 'CiviMix\\Schema\\Twinglecampaign\\DAO'; - class_alias($realClass, $class); - // ^^ Abstract names -- discourage IDE's from picking up on this association. - } - return; - } - - // This allows us to tap-in to the installation process (without incurring real file-reads on typical requests). - if (strpos($class, 'CiviMix\\Schema\\Twinglecampaign\\') === 0) { - // civimix-schema@5 is designed for backported use in download/activation workflows, - // where new revisions may become dynamically available. - pathload()->loadPackage('civimix-schema@5', TRUE); - CiviMix\Schema\loadClass($class); +function _twinglecampaign_civix_mixin_polyfill() { + if (!class_exists('CRM_Extension_MixInfo')) { + $polyfill = __DIR__ . '/mixin/polyfill.php'; + (require $polyfill)(E::LONG_NAME, E::SHORT_NAME, E::path()); } } @@ -120,17 +91,28 @@ function _twinglecampaign_civix_class_loader($class) { * * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_config */ -function _twinglecampaign_civix_civicrm_config($config = NULL) { +function _twinglecampaign_civix_civicrm_config(&$config = NULL) { static $configured = FALSE; if ($configured) { return; } $configured = TRUE; + $template = CRM_Core_Smarty::singleton(); + $extRoot = __DIR__ . DIRECTORY_SEPARATOR; + $extDir = $extRoot . 'templates'; + + if (is_array($template->template_dir)) { + array_unshift($template->template_dir, $extDir); + } + else { + $template->template_dir = [$extDir, $template->template_dir]; + } + $include_path = $extRoot . PATH_SEPARATOR . get_include_path(); set_include_path($include_path); - // Based on , this does not currently require mixin/polyfill.php. + _twinglecampaign_civix_mixin_polyfill(); } /** @@ -140,7 +122,36 @@ function _twinglecampaign_civix_civicrm_config($config = NULL) { */ function _twinglecampaign_civix_civicrm_install() { _twinglecampaign_civix_civicrm_config(); - // Based on , this does not currently require mixin/polyfill.php. + if ($upgrader = _twinglecampaign_civix_upgrader()) { + $upgrader->onInstall(); + } + _twinglecampaign_civix_mixin_polyfill(); +} + +/** + * Implements hook_civicrm_postInstall(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall + */ +function _twinglecampaign_civix_civicrm_postInstall() { + _twinglecampaign_civix_civicrm_config(); + if ($upgrader = _twinglecampaign_civix_upgrader()) { + if (is_callable([$upgrader, 'onPostInstall'])) { + $upgrader->onPostInstall(); + } + } +} + +/** + * Implements hook_civicrm_uninstall(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall + */ +function _twinglecampaign_civix_civicrm_uninstall(): void { + _twinglecampaign_civix_civicrm_config(); + if ($upgrader = _twinglecampaign_civix_upgrader()) { + $upgrader->onUninstall(); + } } /** @@ -150,7 +161,57 @@ function _twinglecampaign_civix_civicrm_install() { */ function _twinglecampaign_civix_civicrm_enable(): void { _twinglecampaign_civix_civicrm_config(); - // Based on , this does not currently require mixin/polyfill.php. + if ($upgrader = _twinglecampaign_civix_upgrader()) { + if (is_callable([$upgrader, 'onEnable'])) { + $upgrader->onEnable(); + } + } + _twinglecampaign_civix_mixin_polyfill(); +} + +/** + * (Delegated) Implements hook_civicrm_disable(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable + * @return mixed + */ +function _twinglecampaign_civix_civicrm_disable(): void { + _twinglecampaign_civix_civicrm_config(); + if ($upgrader = _twinglecampaign_civix_upgrader()) { + if (is_callable([$upgrader, 'onDisable'])) { + $upgrader->onDisable(); + } + } +} + +/** + * (Delegated) Implements hook_civicrm_upgrade(). + * + * @param $op string, the type of operation being performed; 'check' or 'enqueue' + * @param $queue CRM_Queue_Queue, (for 'enqueue') the modifiable list of pending up upgrade tasks + * + * @return mixed + * based on op. for 'check', returns array(boolean) (TRUE if upgrades are pending) + * for 'enqueue', returns void + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade + */ +function _twinglecampaign_civix_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { + if ($upgrader = _twinglecampaign_civix_upgrader()) { + return $upgrader->onUpgrade($op, $queue); + } +} + +/** + * @return CRM_TwingleCampaign_Upgrader + */ +function _twinglecampaign_civix_upgrader() { + if (!file_exists(__DIR__ . '/CRM/TwingleCampaign/Upgrader.php')) { + return NULL; + } + else { + return CRM_TwingleCampaign_Upgrader_Base::instance(); + } } /** @@ -169,8 +230,8 @@ function _twinglecampaign_civix_insert_navigation_menu(&$menu, $path, $item) { if (empty($path)) { $menu[] = [ 'attributes' => array_merge([ - 'label' => $item['name'] ?? NULL, - 'active' => 1, + 'label' => CRM_Utils_Array::value('name', $item), + 'active' => 1, ], $item), ]; return TRUE; @@ -234,3 +295,14 @@ function _twinglecampaign_civix_fixNavigationMenuItems(&$nodes, &$maxNavID, $par } } } + +/** + * (Delegated) Implements hook_civicrm_entityTypes(). + * + * Find any *.entityType.php files, merge their content, and return. + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes + */ +function _twinglecampaign_civix_civicrm_entityTypes(&$entityTypes) { + $entityTypes = array_merge($entityTypes, []); +} diff --git a/twinglecampaign.php b/twinglecampaign.php index 282f7cb..79b016f 100644 --- a/twinglecampaign.php +++ b/twinglecampaign.php @@ -468,6 +468,24 @@ function twinglecampaign_civicrm_install() { _twinglecampaign_civix_civicrm_install(); } +/** + * Implements hook_civicrm_postInstall(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_postInstall + */ +function twinglecampaign_civicrm_postInstall() { + _twinglecampaign_civix_civicrm_postInstall(); +} + +/** + * Implements hook_civicrm_uninstall(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_uninstall + */ +function twinglecampaign_civicrm_uninstall() { + _twinglecampaign_civix_civicrm_uninstall(); +} + /** * Implements hook_civicrm_enable(). * @@ -477,6 +495,35 @@ function twinglecampaign_civicrm_enable() { _twinglecampaign_civix_civicrm_enable(); } +/** + * Implements hook_civicrm_disable(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_disable + */ +function twinglecampaign_civicrm_disable() { + _twinglecampaign_civix_civicrm_disable(); +} + +/** + * Implements hook_civicrm_upgrade(). + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_upgrade + */ +function twinglecampaign_civicrm_upgrade($op, CRM_Queue_Queue $queue = NULL) { + return _twinglecampaign_civix_civicrm_upgrade($op, $queue); +} + +/** + * Implements hook_civicrm_entityTypes(). + * + * Declare entity types provided by this module. + * + * @link https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_entityTypes + */ +function twinglecampaign_civicrm_entityTypes(&$entityTypes) { + _twinglecampaign_civix_civicrm_entityTypes($entityTypes); +} + // --- Functions below this ship commented out. Uncomment as required. --- /**