--- /dev/null
+<?php
+
+namespace Civi\Shimmy\Mixins;
+
+/**
+ * Assert that the 'scan-classes' mixin is working properly.
+ *
+ * This class defines the assertions to run when installing or uninstalling the extension.
+ * It is called as part of E2E_Shimmy_LifecycleTest.
+ *
+ * @see E2E_Shimmy_LifecycleTest
+ */
+class SmartyTest extends \PHPUnit\Framework\Assert {
+
+ public function testPreConditions($cv): void {
+ $this->assertFileExists(static::getPath('/templates/CRM/Shimmy/Example.tpl'), 'The shimmy extension must have example TPL files.');
+ }
+
+ public function testInstalled($cv): void {
+ $out = $this->renderExample($cv, 'CRM/Shimmy/Example.tpl');
+ $this->assertEquals('<p>OK</p>', trim($out));
+ }
+
+ public function testDisabled($cv): void {
+ if ($cv->isLocal()) {
+ // Historically, Smarty templates have been left active for duration of same-process (post-disabling).
+ // We'll ignore testing this edge-case until someone decides that a change in behavior is better.
+ return;
+ }
+
+ $out = $this->renderExample($cv, 'CRM/Shimmy/Example.tpl');
+ $this->assertEquals('', trim($out));
+ }
+
+ public function testUninstalled($cv): void {
+ // Same as disabled....
+ $this->testDisabled($cv);
+ }
+
+ protected static function getPath($suffix = ''): string {
+ return dirname(__DIR__, 2) . $suffix;
+ }
+
+ /**
+ * Render a template with the system-under-test.
+ *
+ * @param $cv
+ * @param string $name
+ * @return string
+ */
+ protected function renderExample($cv, string $name) {
+ try {
+ putenv('SHIMMY_FOOBAR=' . $name);
+ try {
+ return $cv->phpEval('return CRM_Core_Smarty::singleton()->fetch(getenv("SHIMMY_FOOBAR"));');
+ }
+ catch (\Throwable $e) {
+ return '';
+ }
+ }
+ finally {
+ putenv('SHIMMY_FOOBAR');
+ }
+ }
+
+}
--- /dev/null
+<?php
+
+/**
+ * Auto-register "templates/" folder.
+ *
+ * @mixinName smarty-v2
+ * @mixinVersion 1.0.0
+ * @since 5.58
+ *
+ * @param CRM_Extension_MixInfo $mixInfo
+ * On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ * @param \CRM_Extension_BootCache $bootCache
+ * On newer deployments, this will be an instance of MixInfo. On older deployments, Civix may polyfill with a work-a-like.
+ */
+return function ($mixInfo, $bootCache) {
+ $dir = $mixInfo->getPath('templates');
+ if (!file_exists($dir)) {
+ return;
+ }
+
+ // Is it good or bad that this hasn't different static-guard-i-ness than the old 'hook_config' boilerplate?
+
+ if ($mixInfo->isActive()) {
+ \Civi::dispatcher()->addListener('hook_civicrm_config', function () use ($dir) {
+ \CRM_Core_Smarty::singleton()->addTemplateDir($dir);
+ });
+ }
+ elseif (CRM_Extension_System::singleton()->getManager()->extensionIsBeingInstalledOrEnabled($mixInfo->longName)) {
+ \CRM_Core_Smarty::singleton()->addTemplateDir($dir);
+ }
+
+};