All Data Structures Functions Variables Pages
BuilderCanvasWizardView.php
1 <?php
2  /*********************************************************************************
3  * Zurmo is a customer relationship management program developed by
4  * Zurmo, Inc. Copyright (C) 2017 Zurmo Inc.
5  *
6  * Zurmo is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY ZURMO, ZURMO DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  *
13  * Zurmo is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  *
23  * You can contact Zurmo, Inc. with a mailing address at 27 North Wacker Drive
24  * Suite 370 Chicago, IL 60606. or at email address contact@zurmo.com.
25  *
26  * The interactive user interfaces in original and modified versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  *
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the Zurmo
32  * logo and Zurmo copyright notice. If the display of the logo is not reasonably
33  * feasible for technical reasons, the Appropriate Legal Notices must display the words
34  * "Copyright Zurmo Inc. 2017. All rights reserved".
35  ********************************************************************************/
36 
38  {
39  const REFRESH_CANVAS_FROM_SAVED_TEMPLATE_LINK_ID = 'refresh-canvas-from-saved-template';
40 
41  const CACHED_SERIALIZED_DATA_ATTRIBUTE_NAME = 'serializedData';
42 
43  const CANVAS_IFRAME_ID = 'canvas-iframe';
44 
45  const PREVIEW_IFRAME_ID = 'preview-iframe';
46 
47  const PREVIEW_IFRAME_CONTAINER_ID = 'preview-iframe-container';
48 
49  const PREVIEW_IFRAME_CONTAINER_CLOSE_LINK_ID = 'preview-iframe-container-close-link';
50 
51  const ELEMENT_EDIT_CONTAINER_ID = 'element-edit-container';
52 
53  const ELEMENT_EDIT_FORM_OVERLAY_CONTAINER_ID = 'element-edit-form-overlay-container';
54 
55  const UL_ELEMENT_TO_PLACE_ID = 'building-blocks';
56 
57  const ELEMENT_IFRAME_OVERLAY_ID = 'iframe-overlay';
58 
59  const ELEMENTS_MENU_BUTTON_ID = 'builder-elements-menu-button';
60 
61  const CANVAS_CONFIGURATION_MENU_BUTTON_ID = 'builder-canvas-configuration-menu-button';
62 
63  const PREVIEW_MENU_BUTTON_ID = 'builder-preview-menu-button';
64 
65  const ELEMENTS_CONTAINER_ID = 'droppable-element-sidebar';
66 
70  public static function getWizardStepTitle()
71  {
72  return Zurmo::t('EmailTemplatesModule', 'Canvas');
73  }
74 
78  public static function getPreviousPageLinkId()
79  {
80  return 'builderCanvasPreviousLink';
81  }
82 
86  public static function getNextPageLinkId()
87  {
88  return 'builderCanvasSaveLink';
89  }
90 
91  public static function resolveValidationScenario()
92  {
93  return EmailTemplateWizardForm::SERIALIZED_DATA_VALIDATION_SCENARIO;
94  }
95 
96  protected function renderSendTestEmailButton()
97  {
98  return true;
99  }
100 
104  protected function renderFormContent()
105  {
106  $freezeOverlayContent = $this->renderFreezeOverlayContent();
107  $toolbarContent = $this->renderLeftSidebarToolbarContent();
108  $leftSidebarContent = $this->renderLeftSidebarContent();
109  $rightSidebarContent = $this->resolveCanvasContent();
110  $this->wrapContentForLeftSideBar($leftSidebarContent);
111  $this->wrapContentForRightSideBar($rightSidebarContent);
112  $content = $freezeOverlayContent . $toolbarContent .
113  $leftSidebarContent . $rightSidebarContent;
114  $content = ZurmoHtml::tag('div', $this->resolveContentHtmlOptions(), $content);
115  return $content;
116  }
117 
118  protected function renderLeftSidebarContent()
119  {
120  $hiddenElements = null;
121  $leftSidebarContent = $this->resolveElementsSidebarContent();
122  $this->renderHiddenElements($hiddenElements, $leftSidebarContent);
123  $leftSidebarContent .= $this->renderRefreshCanvasLinkContent($leftSidebarContent);
124  return $leftSidebarContent;
125  }
126 
127  protected function renderLeftSidebarToolbarContent()
128  {
129  $content = '<div class="view-toolbar-container clearfix"><nav class="pillbox clearfix">';
130  $element = new EmailTemplateBuilderElementsMenuActionElement('default', 'emailTemplates', null,
131  array('htmlOptions' => array('id'=> static::ELEMENTS_MENU_BUTTON_ID, 'class' => 'active'),
132  'iconClass'=> 'icon-elements'));
133  $content .= $element->render();
134  $element = new EmailTemplateBuilderCanvasConfigurationMenuActionElement('default', 'emailTemplates', null,
135  array('htmlOptions' => array('id'=> static::CANVAS_CONFIGURATION_MENU_BUTTON_ID), 'iconClass'=> 'icon-configuration'));
136  $content .= $element->render();
137  $content .= '</nav><nav class="pillbox clearfix">';
138  $element = new EmailTemplateBuilderPreviewMenuActionElement('default', 'emailTemplates', null,
139  array('htmlOptions' => array('id'=> static::PREVIEW_MENU_BUTTON_ID), 'iconClass'=> 'icon-preview'));
140  $content .= $element->render();
141  $content .= '</nav></div>';
142  return $content;
143  }
144 
145  protected function renderFreezeOverlayContent()
146  {
147  $span = ZurmoHtml::tag('span', array('class' => 'big-spinner'));
148  return ZurmoHtml::tag('div', array('id' => static::ELEMENT_IFRAME_OVERLAY_ID, 'class' => 'ui-overlay-block'), $span);
149  }
150 
151  protected function resolveCachedSerializedDataHiddenInputJQuerySelector()
152  {
153  return '#' . get_class($this->model) . '_' . static::CACHED_SERIALIZED_DATA_ATTRIBUTE_NAME . '_dom';
154  }
155 
156  protected function resolveContentHtmlOptions()
157  {
158  return array('id' => 'builder', 'class' => 'strong-right clearfix');
159  }
160 
161  protected function renderRefreshCanvasLinkContent()
162  {
163  $linkContent = ZurmoHtml::link('Reload Canvas', '#', $this->resolveRefreshCanvasLinkHtmlOptions());
164  //@TODO SHOAIBI, does it need to live in a table?
165  //$this->wrapContentInTableCell($linkContent, array('colspan' => 2));
166  //$this->wrapContentInTableRow($linkContent);
167  return $linkContent;
168  }
169 
170  protected function resolveRefreshCanvasLinkHtmlOptions()
171  {
172  return array('id' => static::REFRESH_CANVAS_FROM_SAVED_TEMPLATE_LINK_ID, 'style' => 'display:none');
173  }
174 
175  protected function generateWidgetTagsForUIAccessibleElements($uiAccessibleElements)
176  {
177  $content = null;
178  foreach ($uiAccessibleElements as $element)
179  {
180  $content .= $element::resolveDroppableWidget('li');
181  }
182  $content = ZurmoHtml::tag('ul', $this->resolveWidgetTagsWrapperHtmlOptions(), $content);
183  return $content;
184  }
185 
186  protected function resolveWidgetTagsWrapperHtmlOptions()
187  {
188  return array('id' => 'building-blocks', 'class' => 'clearfix builder-elements builder-elements-droppable');
189  }
190 
191  protected function resolveElementsSidebarContent()
192  {
193  $uiAccessibleElements = PathUtil::getAllUIAccessibleBuilderElementClassNames();
194  $uiAccessibleContent = $this->generateWidgetTagsForUIAccessibleElements($uiAccessibleElements);
195  $this->wrapContentInDiv($uiAccessibleContent, $this->resolveElementsSidebarHtmlOptions());
196  return $uiAccessibleContent;
197  }
198 
199  protected function resolveElementsSidebarHtmlOptions()
200  {
201  return array('id' => static::ELEMENTS_CONTAINER_ID);
202  }
203 
204  protected function resolveCanvasContent()
205  {
206  $canvasContent = ZurmoHtml::tag('iframe', $this->resolveCanvasIFrameHtmlOptions(), '');
207  return $canvasContent;
208  }
209 
210  protected function resolveCanvasIFrameHtmlOptions()
211  {
212  return array('id' => static::CANVAS_IFRAME_ID,
213  'src' => 'about:blank',
214  'width' => '100%',
215  'height' => '100%',
216  'frameborder' => 0);
217  }
218 
219  protected function registerScripts()
220  {
221  parent::registerScripts();
222  $this->registerEmailTemplateEditorScripts();
223  $this->registerLeftSideToolbarScripts();
224  $this->registerRefreshCanvasFromSavedTemplateScript();
225  }
226 
227  protected function registerEmailTemplateEditorScripts()
228  {
229  $this->registerEmailTemplateEditorScriptFile();
230  $this->registerInitializeEmailTemplateEditorScript();
231  }
232 
233  protected function registerEmailTemplateEditorScriptFile()
234  {
235  $baseScriptUrl = Yii::app()->assetManager->publish(
236  Yii::getPathOfAlias('application.modules.emailTemplates.widgets.assets'));
237  Yii::app()->clientScript->registerScriptFile($baseScriptUrl . '/EmailTemplateEditor.js',
238  CClientScript::POS_HEAD);
239  }
240 
241  protected function registerInitializeEmailTemplateEditorScript()
242  {
243  $elementsContainerId = '#' . static::ELEMENTS_CONTAINER_ID;
244  $elementsToPlaceSelector = '#' . static::UL_ELEMENT_TO_PLACE_ID;
245  $iframeSelector = '#' . static::CANVAS_IFRAME_ID;
246  $editSelector = '#' . static::ELEMENT_EDIT_CONTAINER_ID;
247  $editFormSelector = '#' . static::ELEMENT_EDIT_FORM_OVERLAY_CONTAINER_ID;
248  $editActionSelector = 'span.' . BaseBuilderElement::OVERLAY_ACTION_EDIT;
249  $moveActionSelector = 'span.' . BaseBuilderElement::OVERLAY_ACTION_MOVE;
250  $deleteActionSelector = 'span.' . BaseBuilderElement::OVERLAY_ACTION_DELETE;
254  $iframeOverlaySelector = '#' . static::ELEMENT_IFRAME_OVERLAY_ID;
255  $cachedSerializedSelector = static::resolveCachedSerializedDataHiddenInputJQuerySelector();
256  $errorOnDeleteMessage = Zurmo::t('EmailTemplatesModule', 'Cannot delete last row');
257  $dropHereMessage = Zurmo::t('Core', 'Drop here');
258  $csrfToken = Yii::app()->request->csrfToken;
259  $doNotWrapInRow = BuilderElementRenderUtil::DO_NOT_WRAP_IN_ROW;
260  $wrapInRow = BuilderElementRenderUtil::WRAP_IN_ROW;
261  $wrapInHeaderRow = BuilderElementRenderUtil::WRAP_IN_HEADER_ROW;
262  $modelClassName = BaseBuilderElement::getModelClassName();
263  $editableActionUrl = static::resolveElementEditableActionUrl();
264  $nonEditableActionUrl = static::resolveElementNonEditableActionUrl();
265  Yii::app()->getClientScript()->registerScript('initializeEmailTemplateEditor', "
266  initEmailTemplateEditor = function () {
267  emailTemplateEditor.init(
268  '{$elementsContainerId}',
269  '{$elementsToPlaceSelector}',
270  '{$iframeSelector}',
271  '{$editSelector}',
272  '{$editFormSelector}',
273  '{$editActionSelector}',
274  '{$moveActionSelector}',
275  '{$deleteActionSelector}',
276  '{$sortableRowsClass}',
277  '{$sortableElementsClass}',
278  '{$cellDroppableClass}',
279  '{$iframeOverlaySelector}',
280  '{$cachedSerializedSelector}',
281  '{$editableActionUrl}',
282  '{$nonEditableActionUrl}',
283  '{$errorOnDeleteMessage}',
284  '{$dropHereMessage}',
285  '{$csrfToken}',
286  {$doNotWrapInRow},
287  {$wrapInRow},
288  {$wrapInHeaderRow},
289  '{$modelClassName}'
290  );
291  };
292  ", CClientScript::POS_END);
293  }
294 
295  protected function registerRefreshCanvasFromSavedTemplateScript()
296  {
297  Yii::app()->clientScript->registerScript('refreshCanvasFromSavedTemplateScript', "
298  $('#" . static::REFRESH_CANVAS_FROM_SAVED_TEMPLATE_LINK_ID . "').unbind('click').bind('click', function(event)
299  {
300  emailTemplateEditor.reloadCanvas();
301  event.preventDefault();
302  });
303  ", CClientScript::POS_READY);
304  }
305 
306  protected function registerLeftSideToolbarScripts()
307  {
308  $this->registerElementsMenuButtonClickScript();
309  $this->registerCanvasConfigurationMenuButtonClickScript();
310  $this->registerPreviewMenuButtonClickScript();
311  }
312 
313  protected function registerElementsMenuButtonClickScript()
314  {
315  // Begin Not Coding Standard
316  Yii::app()->clientScript->registerScript('elementsMenuButtonClickScript', '
317  $("#' . static::ELEMENTS_MENU_BUTTON_ID . '").unbind("click.elementsMenuButtonClickScript")
318  .bind("click.elementsMenuButtonClickScript", function(event)
319  {
320  if(!$("#' . static::ELEMENTS_MENU_BUTTON_ID . '").hasClass("active"))
321  {
322  $("#' . static::ELEMENTS_MENU_BUTTON_ID . '").addClass("active");
323  }
324  $("#' . static::CANVAS_CONFIGURATION_MENU_BUTTON_ID . '").removeClass("active");
325  $("#' . static::ELEMENT_EDIT_CONTAINER_ID . '").hide();
326  $("#' . static::ELEMENTS_CONTAINER_ID . '").show();
327  event.preventDefault();
328  });');
329  // End Not Coding Standard
330  }
331 
332  protected function registerCanvasConfigurationMenuButtonClickScript()
333  {
334  // Begin Not Coding Standard
335  Yii::app()->clientScript->registerScript('canvasConfigurationMenuButtonClickScript', '
336  $("#' . static::CANVAS_CONFIGURATION_MENU_BUTTON_ID . '").unbind("click.canvasConfigurationMenuButtonClick")
337  .bind("click.canvasConfigurationMenuButtonClick", function(event)
338  {
339  if(!$("#' . static::CANVAS_CONFIGURATION_MENU_BUTTON_ID . '").hasClass("active"))
340  {
341  $("#' . static::CANVAS_CONFIGURATION_MENU_BUTTON_ID . '").addClass("active");
342  }
343  $("#' . static::ELEMENTS_MENU_BUTTON_ID . '").removeClass("active");
344  $("#' . static::ELEMENTS_CONTAINER_ID . '").hide();
345  $("#' . static::CANVAS_IFRAME_ID . '").contents()
346  .find(".builder-element-non-editable.element-data.body")
348  .find(".' . BaseBuilderElement::OVERLAY_ACTION_EDIT . '").trigger("click");
349  event.preventDefault();
350  });');
351  // End Not Coding Standard
352  }
353 
354  protected function registerPreviewMenuButtonClickScript()
355  {
356  $ajaxOption = $this->resolvePreviewAjaxOptions();
357  // Begin Not Coding Standard
358  Yii::app()->clientScript->registerScript('previewMenuButtonClickScript', '
359  $("#' . static::PREVIEW_MENU_BUTTON_ID . '").unbind("click.previewMenuButtonClick")
360  .bind("click.previewMenuButtonClick", function(event){
361  ' . ZurmoHtml::ajax($ajaxOption) . '
362  $("body").addClass("previewing-builder");
363  event.preventDefault();
364  });');
365  // End Not Coding Standard
366  }
367 
368  protected function resolvePreviewAjaxOptions()
369  {
370  $message = Zurmo::t('EmailTemplatesModule', 'There was an error generating preview');
371  $ajaxArray = static::resolveErrorAjaxCallback($message);
372  $ajaxArray['cache'] = 'false';
373  $ajaxArray['url'] = static::resolvePreviewActionUrl();
374  $ajaxArray['type'] = 'POST';
375  // Begin Not Coding Standard
376  $ajaxArray['data'] = 'js:(function(){
377  jsonSerializedData = {dom: $.parseJSON(emailTemplateEditor.compileSerializedData())};
378  serializedData = JSON.stringify(jsonSerializedData);
379  requestData = {serializedData: serializedData,
380  "YII_CSRF_TOKEN": "' . addslashes(Yii::app()->request->csrfToken) .
381  '"};
382  return requestData;
383  })()';
384  $ajaxArray['beforeSend'] = 'js:function(){
385  $("#' . static::PREVIEW_IFRAME_CONTAINER_ID . '").show();
386  }';
387  $ajaxArray['success'] = 'js:function (html){
388  $("#' . static::PREVIEW_IFRAME_ID . '").contents().find("html").html(html);
389  }';
390  // End Not Coding Standard
391  return $ajaxArray;
392  }
393 
394  protected static function resolveCompleteAjaxCallbackForSpinnerRemoval($formName)
395  {
396  $script = "emailTemplateEditor.unfreezeLayoutEditor();";
397  $parentScript = parent::resolveCompleteAjaxCallbackForSpinnerRemoval($formName);
398  $script = $script . PHP_EOL . $parentScript;
399  return $script;
400  }
401 
402  protected static function resolveSuccessAjaxCallbackForPageTransition($formName, $nextPageClassName,
403  $validationInputId, $progressPerStep,
404  $stepCount, $model)
405  {
406  $script = static::resolveHideCanvasScript();
407  $parentScript = parent::resolveSuccessAjaxCallbackForPageTransition($formName,
408  $nextPageClassName,
409  $validationInputId,
410  $progressPerStep,
411  $stepCount, $model);
412  $script = $script . PHP_EOL . $parentScript;
413  return $script;
414  }
415 
416  public static function resolvePreviousPageScript(& $script)
417  {
418  $script = static::resolveHideCanvasScript() . PHP_EOL . $script;
419  }
420 
421  protected static function resolveHideCanvasScript()
422  {
423  return "$('#" . static::ELEMENT_EDIT_CONTAINER_ID . "').hide();";
424  }
425  }
426 ?>
const BUILDER_ELEMENT_SORTABLE_ROWS_CLASS
const BUILDER_ELEMENT_SORTABLE_ELEMENTS_CLASS
const BUILDER_ELEMENT_CELL_DROPPABLE_CLASS
Generated on Tue May 26 2020 07:10:31