Commit 882b14c4 authored by Mathieu Lutfy's avatar Mathieu Lutfy Committed by Aegir user

Update mosaico to 2.0-beta4

parent 45656722
# APIv3
CiviCRM's APIv3 framework provides a way for consumers to manage data and call services. APIv3 can be called in many ways
(such as PHP, REST, and CLI). For a general introduction, see [APIv3 Intro](https://docs.civicrm.org/dev/en/latest/api/).
This extension defines a few new APIs:
* `Job.mosaico_migrate`: If you need to perform an automated migration from v1.x to v2.x, use this API to copy all
v1.x templates to v2.x.
* `Job.mosaico_purge`: If you need to perform an automated migration from v1.x to v2.x, use this API to clear out the
old v1.x templates.
* `MosaicoTemplate.*`: This API provides access to the user-configurable templates. It supports all standard CRUD
actions (`get`, `create`, `delete`etc). Its data-structure closely adheres to Mosaico's canonical storage format.
* `MosaicoBaseTemplate.get`: This API provides access to the *base templates*. A base template (such as `versafix-1`)
defines the HTML blocks that are available for drag/drop in the Mosaico palette. Note: This API is *read-only*.
To define custom templates, see the section on "Base templates".
# Base templates
A base template defines the HTML blocks that are available for drag/drop in the Mosaico palette. The standard distribution
of Mosaico includes a few base templates, such as `versafix-1`.
The upstream Mosaico project provides a tutorial on how to develop a custom base template:
https://github.com/voidlabs/mosaico/blob/master/templates/tutorial/mosaico-tutorial.md
The new template is essentially a folder with a couple standard files. Once you've developed these files, you'll need
a way to *deploy* the folder, such as:
* __Drop-in folder__: On any site, create a folder dedicated to custom base templates. By default, this is
`[civicrm.files]/mosaico_tpl`. (`[civicrm.files]` is a variable that resolves somewhere under the CMS's data
folder.) For example, if you deployed a template `foobar` on a typical Drupal 7 site, the full path to the template HTML
might be `/var/www/sites/default/files/civicrm/mosaico_tpl/foobar/template-foobar.html`. (The folder name can be
customized in "Administer => CiviMail => Mosaico Settings".)
* __Extension__: Create a CiviCRM extension and put the template in it. Use the [hook system](https://docs.civicrm.org/dev/en/latest/hooks/) to register the template via `hook_civicrm_mosaicoBaseTemplates`. For example, this snippet shows how an extension named `mymodule` can register a base-template named `foobar`:
```php
<?php
use CRM_Mymodule_ExtensionUtil as E;
function mymodule_civicrm_mosaicoBaseTemplates(&$templates) {
$templates['foobar'] = array(
'name' => 'foobar',
'title' => 'Foo Bar',
'path' => E::url('foobar/template-foobar.html'),
'thumbnail' => E::url('foobar/edres/_full.png'),
);
}
```
# Delivery
After designing a mailing, email messages are composed and delivered through FlexMailer. To programmaticaly tap into the
composition and delivery process, see the [FlexMailer developer docs](https://docs.civicrm.org/flexmailer/en/latest/).
...@@ -38,20 +38,41 @@ class CRM_Mosaico_BAO_MosaicoTemplate extends CRM_Mosaico_DAO_MosaicoTemplate { ...@@ -38,20 +38,41 @@ class CRM_Mosaico_BAO_MosaicoTemplate extends CRM_Mosaico_DAO_MosaicoTemplate {
$templatesUrl = CRM_Mosaico_Utils::getTemplatesUrl('absolute'); $templatesUrl = CRM_Mosaico_Utils::getTemplatesUrl('absolute');
$templatesLocation[] = array('dir' => $templatesDir, 'url' => $templatesUrl);
$customTemplatesDir = \Civi::paths()->getPath(CRM_Core_BAO_Setting::getItem('Mosaico Preferences', 'mosaico_custom_templates_dir'));
$customTemplatesUrl = \Civi::paths()->getUrl(CRM_Core_BAO_Setting::getItem('Mosaico Preferences', 'mosaico_custom_templates_url'));
if (!is_null($customTemplatesDir) && !is_null($customTemplatesUrl)) {
if (is_dir($customTemplatesDir)) {
$templatesLocation[] = array('dir' => $customTemplatesDir, 'url' => $customTemplatesUrl);
}
}
$records = array(); $records = array();
foreach (glob("{$templatesDir}/*", GLOB_ONLYDIR) as $dir) { foreach ($templatesLocation as $templateLocation) {
$template = basename($dir); foreach (glob("{$templateLocation['dir']}/*", GLOB_ONLYDIR) as $dir) {
$templateHTML = "{$templatesUrl}/{$template}/template-{$template}.html"; $template = basename($dir);
$templateThumbnail = "{$templatesUrl}/{$template}/edres/_full.png"; $templateHTML = "{$templateLocation['url']}/{$template}/template-{$template}.html";
$templateThumbnail = "{$templateLocation['url']}/{$template}/edres/_full.png";
$records[] = array( $records[$template] = array(
'name' => $template, 'name' => $template,
'title' => $template, 'title' => $template,
'thumbnail' => $templateThumbnail, 'thumbnail' => $templateThumbnail,
'path' => $templateHTML, 'path' => $templateHTML,
);
}
}
if (class_exists('\Civi\Core\Event\GenericHookEvent')) {
\Civi::dispatcher()->dispatch('hook_civicrm_mosaicoBaseTemplates',
\Civi\Core\Event\GenericHookEvent::create(array(
'templates' => &$records,
))
); );
} }
Civi::$statics[__CLASS__]['bases'] = $records; Civi::$statics[__CLASS__]['bases'] = $records;
} }
......
...@@ -115,6 +115,12 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO { ...@@ -115,6 +115,12 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO {
* @var longtext * @var longtext
*/ */
public $content; public $content;
/**
* FK to civicrm_msg_template.
*
* @var int unsigned
*/
public $msg_tpl_id;
/** /**
* class constructor * class constructor
* *
...@@ -124,6 +130,19 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO { ...@@ -124,6 +130,19 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO {
$this->__table = 'civicrm_mosaico_template'; $this->__table = 'civicrm_mosaico_template';
parent::__construct(); parent::__construct();
} }
/**
* Returns foreign keys and entity references
*
* @return array
* [CRM_Core_Reference_Interface]
*/
static function getReferenceColumns() {
if (!self::$_links) {
self::$_links = static ::createReferenceColumns(__CLASS__);
self::$_links[] = new CRM_Core_Reference_Basic(self::getTableName() , 'msg_tpl_id', 'civicrm_msg_template', 'id');
}
return self::$_links;
}
/** /**
* Returns all the column names of this table * Returns all the column names of this table
* *
...@@ -144,7 +163,7 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO { ...@@ -144,7 +163,7 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO {
'title' => ts('Title') , 'title' => ts('Title') ,
'description' => 'Title', 'description' => 'Title',
'maxlength' => 255, 'maxlength' => 255,
'size' => CRM_Utils_Type::BIG, 'size' => CRM_Utils_Type::HUGE,
) , ) ,
'base' => array( 'base' => array(
'name' => 'base', 'name' => 'base',
...@@ -172,6 +191,22 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO { ...@@ -172,6 +191,22 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO {
'title' => ts('Content') , 'title' => ts('Content') ,
'description' => 'Mosaico content (JSON)', 'description' => 'Mosaico content (JSON)',
) , ) ,
'msg_tpl_id' => array(
'name' => 'msg_tpl_id',
'type' => CRM_Utils_Type::T_INT,
'title' => ts('message template ID') ,
'description' => 'FK to civicrm_msg_template.',
'required' => false,
'FKClassName' => 'CRM_Core_DAO_MessageTemplate',
'html' => array(
'type' => 'Select',
) ,
'pseudoconstant' => array(
'table' => 'civicrm_msg_template',
'keyColumn' => 'id',
'labelColumn' => 'msg_title',
)
) ,
); );
} }
return self::$_fields; return self::$_fields;
...@@ -191,6 +226,7 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO { ...@@ -191,6 +226,7 @@ class CRM_Mosaico_DAO_MosaicoTemplate extends CRM_Core_DAO {
'html' => 'html', 'html' => 'html',
'metadata' => 'metadata', 'metadata' => 'metadata',
'content' => 'content', 'content' => 'content',
'msg_tpl_id' => 'msg_tpl_id',
); );
} }
return self::$_fieldKeys; return self::$_fieldKeys;
......
<?php
use CRM_Mosaico_ExtensionUtil as E;
/**
* Form controller class
*
* @see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference
*/
class CRM_Mosaico_Form_Migrate extends CRM_Core_Form {
public function buildQuickForm() {
$this->loadTemplateData();
$migrateComment = E::ts('Are you sure want to copy data from Mosaico 1.x to 2.x?') . '\n' . E::ts('This action cannot be easily undone.');
$purgeComment = E::ts('Are you sure want to purge Mosaico 1.x data?') . '\n' . E::ts('This action cannot be undone.');
$buttons = array();
$buttons[] = array(
'type' => 'submit',
'name' => ts('Copy'),
'subName' => 'migrate',
'isDefault' => TRUE,
'icon' => 'fa-copy',
'js' => array('onclick' => 'return confirm(\'' . $migrateComment . '\');'),
);
$buttons[] = array(
'type' => 'submit',
'name' => ts('Purge'),
'subName' => 'purge',
'icon' => 'fa-trash',
'isDefault' => FALSE,
'js' => array('onclick' => 'return confirm(\'' . $purgeComment . '\');'),
);
$this->addButtons($buttons);
// export form elements
$this->assign('elementNames', $this->getRenderableElementNames());
parent::buildQuickForm();
}
public function postProcess() {
$values = $this->exportValues();
if (!empty($values['_qf_Migrate_submit_migrate'])) {
$apiResult = civicrm_api3('Job', 'mosaico_migrate', array(
'check_permissions' => 1,
));
CRM_Core_Session::setStatus(E::ts('Copied %1 templates from Mosaico 1.x to 2.x.', array(
1 => $apiResult['count'],
)), '', 'success', array(
'expires' => 0,
));
}
elseif (!empty($values['_qf_Migrate_submit_purge'])) {
civicrm_api3('Job', 'mosaico_purge', array(
'check_permissions' => 1,
));
CRM_Core_Session::setStatus(E::ts('Purged invisible Mosaico 1.x data.', array()), '', 'success', array(
'expires' => 0,
));
}
else {
CRM_Core_Session::setStatus(E::ts('Unrecognized action'));
}
$this->loadTemplateData();
parent::postProcess();
}
/**
* Get the fields/elements defined in this form.
*
* @return array (string)
*/
public function getRenderableElementNames() {
// The _elements list includes some items which should not be
// auto-rendered in the loop -- such as "qfKey" and "buttons". These
// items don't have labels. We'll identify renderable by filtering on
// the 'label'.
$elementNames = array();
foreach ($this->_elements as $element) {
/** @var HTML_QuickForm_Element $element */
$label = $element->getLabel();
if (!empty($label)) {
$elementNames[] = $element->getName();
}
}
return $elementNames;
}
protected function loadTemplateData() {
$oldTemplates = CRM_Core_DAO::executeQuery('SELECT id, name, msg_tpl_id FROM civicrm_mosaico_msg_template')
->fetchAll();
$newTemplates = CRM_Core_DAO::executeQuery('SELECT id, title, msg_tpl_id FROM civicrm_mosaico_template')
->fetchAll();
$this->assign('oldTemplates', $oldTemplates);
$this->assign('newTemplates', $newTemplates);
$msgTplIds = array_filter(CRM_Utils_Array::collect('msg_tpl_id', $newTemplates), 'is_numeric');
sort($msgTplIds);
$uniqueIds = array_unique($msgTplIds);
$this->assign('msgTplWarning', count($msgTplIds) > count($uniqueIds));
}
}
...@@ -11,6 +11,8 @@ class CRM_Mosaico_Form_MosaicoAdmin extends CRM_Admin_Form_Setting { ...@@ -11,6 +11,8 @@ class CRM_Mosaico_Form_MosaicoAdmin extends CRM_Admin_Form_Setting {
protected $_settings = array( protected $_settings = array(
'mosaico_layout' => 'Mosaico Preferences', 'mosaico_layout' => 'Mosaico Preferences',
'mosaico_custom_templates_dir' => 'Mosaico Custom Templates Directory',
'mosaico_custom_templates_url' => 'Mosaico Custom Templates URL'
); );
/** /**
......
...@@ -63,7 +63,7 @@ class CRM_Mosaico_Page_Editor extends CRM_Core_Page { ...@@ -63,7 +63,7 @@ class CRM_Mosaico_Page_Editor extends CRM_Core_Page {
return array( return array(
'imgProcessorBackend' => $this->getUrl('civicrm/mosaico/img', NULL, TRUE), 'imgProcessorBackend' => $this->getUrl('civicrm/mosaico/img', NULL, TRUE),
'emailProcessorBackend' => $this->getUrl('civicrm/mosaico/dl', NULL, FALSE), 'emailProcessorBackend' => 'unused-emailProcessorBackend',
'titleToken' => 'MOSAICO Responsive Email Designer', 'titleToken' => 'MOSAICO Responsive Email Designer',
'fileuploadConfig' => array( 'fileuploadConfig' => array(
'url' => $this->getUrl('civicrm/mosaico/upload', NULL, FALSE), 'url' => $this->getUrl('civicrm/mosaico/upload', NULL, FALSE),
......
...@@ -103,6 +103,27 @@ class CRM_Mosaico_Upgrader extends CRM_Mosaico_Upgrader_Base { ...@@ -103,6 +103,27 @@ class CRM_Mosaico_Upgrader extends CRM_Mosaico_Upgrader_Base {
return TRUE; return TRUE;
} }
/**
* Add menu for traditional mailing.
*/
public function upgrade_4704() {
$this->ctx->log->info('Applying update 4704');
CRM_Core_DAO::executeQuery('
ALTER TABLE civicrm_mosaico_template
ADD COLUMN `msg_tpl_id` int unsigned NULL COMMENT \'FK to civicrm_msg_template.\'
');
CRM_Core_DAO::executeQuery('
ALTER TABLE civicrm_mosaico_template
ADD CONSTRAINT FK_civicrm_mosaico_template_msg_tpl_id
FOREIGN KEY (`msg_tpl_id`) REFERENCES `civicrm_msg_template`(`id`)
ON DELETE SET NULL
');
return TRUE;
}
/** /**
* Example: Run an external SQL script. * Example: Run an external SQL script.
* *
......
<?php <?php
// AUTO-GENERATED FILE -- Civix may overwrite any changes made to this file // AUTO-GENERATED FILE -- Civix may overwrite any changes made to this file
use CRM_Mosaico_ExtensionUtil as E;
/** /**
* Base class which provides helpers to execute upgrade logic * Base class which provides helpers to execute upgrade logic
...@@ -32,6 +33,12 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -32,6 +33,12 @@ class CRM_Mosaico_Upgrader_Base {
*/ */
private $revisions; private $revisions;
/**
* @var boolean
* Flag to clean up extension revision data in civicrm_setting
*/
private $revisionStorageIsDeprecated = FALSE;
/** /**
* Obtain a reference to the active upgrade handler. * Obtain a reference to the active upgrade handler.
*/ */
...@@ -91,7 +98,6 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -91,7 +98,6 @@ class CRM_Mosaico_Upgrader_Base {
* @return bool * @return bool
*/ */
protected static function executeCustomDataFileByAbsPath($xml_file) { protected static function executeCustomDataFileByAbsPath($xml_file) {
require_once 'CRM/Utils/Migrate/Import.php';
$import = new CRM_Utils_Migrate_Import(); $import = new CRM_Utils_Migrate_Import();
$import->run($xml_file); $import->run($xml_file);
return TRUE; return TRUE;
...@@ -107,7 +113,26 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -107,7 +113,26 @@ class CRM_Mosaico_Upgrader_Base {
public function executeSqlFile($relativePath) { public function executeSqlFile($relativePath) {
CRM_Utils_File::sourceSQLFile( CRM_Utils_File::sourceSQLFile(
CIVICRM_DSN, CIVICRM_DSN,
$this->extensionDir . '/' . $relativePath $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; return TRUE;
} }
...@@ -121,7 +146,7 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -121,7 +146,7 @@ class CRM_Mosaico_Upgrader_Base {
*/ */
public function executeSql($query, $params = array()) { public function executeSql($query, $params = array()) {
// FIXME verify that we raise an exception on error // FIXME verify that we raise an exception on error
CRM_Core_DAO::executeSql($query, $params); CRM_Core_DAO::executeQuery($query, $params);
return TRUE; return TRUE;
} }
...@@ -222,22 +247,37 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -222,22 +247,37 @@ class CRM_Mosaico_Upgrader_Base {
} }
public function getCurrentRevision() { public function getCurrentRevision() {
// return CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName); $revision = CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName);
if (!$revision) {
$revision = $this->getCurrentRevisionDeprecated();
}
return $revision;
}
private function getCurrentRevisionDeprecated() {
$key = $this->extensionName . ':version'; $key = $this->extensionName . ':version';
return CRM_Core_BAO_Setting::getItem('Extension', $key); if ($revision = CRM_Core_BAO_Setting::getItem('Extension', $key)) {
$this->revisionStorageIsDeprecated = TRUE;
}
return $revision;
} }
public function setCurrentRevision($revision) { public function setCurrentRevision($revision) {
// We call this during hook_civicrm_install, but the underlying SQL CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision);
// UPDATE fails because the extension record hasn't been INSERTed yet. // clean up legacy schema version store (CRM-19252)
// Instead, track revisions in our own namespace. $this->deleteDeprecatedRevision();
// CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision);
$key = $this->extensionName . ':version';
CRM_Core_BAO_Setting::setItem($revision, 'Extension', $key);
return TRUE; 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 ******** // ******** Hook delegates ********
/** /**
...@@ -250,6 +290,12 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -250,6 +290,12 @@ class CRM_Mosaico_Upgrader_Base {
CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $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'); $files = glob($this->extensionDir . '/xml/*_install.xml');
if (is_array($files)) { if (is_array($files)) {
foreach ($files as $file) { foreach ($files as $file) {
...@@ -259,13 +305,31 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -259,13 +305,31 @@ class CRM_Mosaico_Upgrader_Base {
if (is_callable(array($this, 'install'))) { if (is_callable(array($this, 'install'))) {
$this->install(); $this->install();
} }
}
/**
* @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_postInstall
*/
public function onPostInstall() {
$revisions = $this->getRevisions(); $revisions = $this->getRevisions();
if (!empty($revisions)) { if (!empty($revisions)) {
$this->setCurrentRevision(max($revisions)); $this->setCurrentRevision(max($revisions));
} }
if (is_callable(array($this, 'postInstall'))) {
$this->postInstall();
}
} }
/**
* @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_uninstall
*/
public function onUninstall() { 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'))) { if (is_callable(array($this, 'uninstall'))) {
$this->uninstall(); $this->uninstall();
} }
...@@ -275,9 +339,11 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -275,9 +339,11 @@ class CRM_Mosaico_Upgrader_Base {
CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file); CRM_Utils_File::sourceSQLFile(CIVICRM_DSN, $file);
} }
} }
$this->setCurrentRevision(NULL);
} }
/**
* @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_enable
*/
public function onEnable() { public function onEnable() {
// stub for possible future use // stub for possible future use
if (is_callable(array($this, 'enable'))) { if (is_callable(array($this, 'enable'))) {
...@@ -285,6 +351,9 @@ class CRM_Mosaico_Upgrader_Base { ...@@ -285,6 +351,9 @@ class CRM_Mosaico_Upgrader_Base {
} }
} }
/**
* @see https://wiki.civicrm.org/confluence/display/CRMDOC/hook_civicrm_disable
*/
public function onDisable() { public function onDisable() {
// stub for possible future use // stub for possible future use
if (is_callable(array($this, 'disable'))) { if (is_callable(array($this, 'disable'))) {
......
...@@ -21,14 +21,14 @@ class CRM_Mosaico_UrlFilter extends \Civi\FlexMailer\Listener\BaseListener { ...@@ -21,14 +21,14 @@ class CRM_Mosaico_UrlFilter extends \Civi\FlexMailer\Listener\BaseListener {
return; return;
} }
SimpleFilter::byColumn($e, 'html', array($this, 'filterHtml')); SimpleFilter::byValue($e, 'html', array($this, 'filterHtml'));
} }
/** /**
* Find any image URLs and ensure they're absolute (not relative). * Find any image URLs and ensure they're absolute (not relative).
* *
* @param array<string> $htmls * @param string|array<string> $htmls
* @return array<string> * @return string|array<string>
* Filtered HTML, with relative IMG url's changed to absolute URLs. * Filtered HTML, with relative IMG url's changed to absolute URLs.
*/ */
public function filterHtml($htmls) { public function filterHtml($htmls) {
......
...@@ -10,6 +10,10 @@ use CRM_Mosaico_ExtensionUtil as E; ...@@ -10,6 +10,10 @@ use CRM_Mosaico_ExtensionUtil as E;
*/ */
class CRM_Mosaico_Utils { class CRM_Mosaico_Utils {
public static function isBootstrap() {
return strpos(CRM_Mosaico_Utils::getLayoutPath(), '/crmstar-') === FALSE;
}
/** /**
* Get a list of layout options. * Get a list of layout options.
* *
...@@ -19,6 +23,7 @@ class CRM_Mosaico_Utils { ...@@ -19,6 +23,7 @@ class CRM_Mosaico_Utils {
public static function getLayoutOptions() { public static function getLayoutOptions() {
return array( return array(
'auto' => E::ts('Automatically select a layout'), 'auto' => E::ts('Automatically select a layout'),
'crmstar-single' => E::ts('Single Page (crm-*)'),
'bootstrap-single' => E::ts('Single Page (Bootstrap CSS)'), 'bootstrap-single' => E::ts('Single Page (Bootstrap CSS)'),
'bootstrap-wizard' => E::ts('Wizard (Bootstrap CSS)'), 'bootstrap-wizard' => E::ts('Wizard (Bootstrap CSS)'),
); );
...@@ -35,17 +40,22 @@ class CRM_Mosaico_Utils { ...@@ -35,17 +40,22 @@ class CRM_Mosaico_Utils {
$layout = CRM_Core_BAO_Setting::getItem('Mosaico Preferences', 'mosaico_layout'); $layout = CRM_Core_BAO_Setting::getItem('Mosaico Preferences', 'mosaico_layout');
$prefix = '~/crmMosaico/EditMailingCtrl'; $prefix = '~/crmMosaico/EditMailingCtrl';
switch ($layout) { $paths = array(
case '': 'crmstar-single' => "$prefix/crmstar-single.html",
case 'auto':