Skip to content

Commit

Permalink
add clips support for the View
Browse files Browse the repository at this point in the history
  • Loading branch information
klimov-paul committed May 10, 2024
1 parent 04557fd commit a97757d
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 6 deletions.
57 changes: 52 additions & 5 deletions src/View.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
namespace yii1tech\mailer;

use CFileHelper;
use CMap;
use Yii;
use yii1tech\mailer\widgets\ClipWidget;

/**
* View is a email template view renderer.
Expand All @@ -14,6 +16,7 @@
*
* @property string $viewPath the root directory of view files. Defaults to 'views/mail' under the application base path.
* @property \IViewRenderer|\CViewRenderer|array|string|null|false $viewRenderer view renderer or its array configuration.
* @property \CMap $clips The list of clips.
*
* @author Paul Klimov <[email protected]>
* @since 1.0
Expand All @@ -38,6 +41,12 @@ class View extends \CBaseController
*/
private $_viewRenderer;

/**
* @var \CMap|null list of clips.
* @see \CClipWidget
*/
private $_clips;

/**
* @return string the root directory of view files. Defaults to 'views/mail' under the application base path.
*/
Expand Down Expand Up @@ -178,21 +187,19 @@ public function render(string $view, ?array $data = null, ?string $locale = null
$content = $this->renderPartial($this->layout, ['content' => $content], true);
}
} catch (\Throwable $e) {
throw $e;
} finally {
while (ob_get_level() > $obInitialLevel) {
if (!@ob_end_clean()) {
ob_clean();
}
}

$this->layout = $originalLayout;
$this->_clips = null;
Yii::app()->setLanguage($originalLocale);

throw $e;
}

$this->layout = $originalLayout;
Yii::app()->setLanguage($originalLocale);

return $content;
}

Expand Down Expand Up @@ -220,4 +227,44 @@ public function renderPartial(string $view, ?array $data = null, bool $return =

return $this->renderFile($viewFile, $data, $return);
}

/**
* Returns the list of clips.
* A clip is a named piece of rendering result that can be inserted at different places.
*
* @see \yii1tech\mailer\widgets\ClipWidget
*
* @return \CMap the list of clips
*/
public function getClips(): CMap
{
if ($this->_clips === null) {
$this->_clips = new CMap();
}

return $this->_clips;
}

/**
* Begins recording a clip.
* This method is a shortcut to beginning {@see \yii1tech\mailer\widgets\ClipWidget}.
*
* @param string $id the clip ID.
* @param array $properties initial property values for {@see \yii1tech\mailer\widgets\ClipWidget}.
*/
public function beginClip($id, $properties = []): void
{
$properties['id'] = $id;
$properties['view'] = $this;
$this->beginWidget(ClipWidget::class, $properties);
}

/**
* Ends recording a clip.
* This method is an alias to {@see endWidget()}.
*/
public function endClip(): void
{
$this->endWidget(ClipWidget::class);
}
}
52 changes: 52 additions & 0 deletions src/widgets/ClipWidget.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

namespace yii1tech\mailer\widgets;

use CWidget;

/**
* ClipWidget records its content and makes it available elsewhere.
*
* This is a replacement for standard {@see \CClipWidget}, which can integrate into {@see \yii1tech\mailer\View}.
*
* @see \yii1tech\mailer\View::beginClip()
*
* @author Paul Klimov <[email protected]>
* @since 1.0
*/
class ClipWidget extends CWidget
{
/**
* @var \CBaseController|\yii1tech\mailer\View view, which renders this widget.
*/
public $view;

/**
* @var bool whether to render the clip content in place. Defaults to false,
* meaning the captured clip will not be displayed.
*/
public $renderClip = false;

/**
* Starts recording a clip.
*/
public function init()
{
ob_start();
ob_implicit_flush(false);
}

/**
* Ends recording a clip.
* This method stops output buffering and saves the rendering result as a named clip in the controller.
*/
public function run()
{
$clip = ob_get_clean();
if ($this->renderClip) {
echo $clip;
}

$this->view->getClips()->add($this->getId(), $clip);
}
}
2 changes: 1 addition & 1 deletion tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected function tearDown(): void
* @param array $config The application configuration, if needed
* @param string $appClass name of the application class to create
*/
protected function mockApplication($config = [], $appClass = CConsoleApplication::class)
protected function mockApplication($config = [], $appClass = \CWebApplication::class)
{
Yii::setApplication(null);

Expand Down
2 changes: 2 additions & 0 deletions tests/ViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,10 @@ public function testRestoreOrigins(): void
$this->assertStringContainsString('Locale = ru', $content);
$this->assertStringContainsString('<!--Header-->', $content);
$this->assertStringContainsString('<!--Footer-->', $content);
$this->assertStringContainsString('Clip = Test Clip Content', $content);

$this->assertSame('default-layout', $view->layout);
$this->assertSame('en_us', Yii::app()->getLanguage());
$this->assertCount(0, $view->getClips());
}
}
6 changes: 6 additions & 0 deletions tests/views/mail/layout.php
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
<?php
/**
* @var $this \yii1tech\mailer\View
*/
?>
<!--Header-->
<?php echo $content; ?>
Clip = <?php echo $this->getClips()->itemAt('test-clip') ?>
<!--Footer-->
3 changes: 3 additions & 0 deletions tests/views/mail/switch.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@
Test switch mail template
Name = <?php echo $name; ?>
Locale = <?php echo Yii::app()->getLanguage(); ?>
<?php $this->beginClip('test-clip'); ?>
Test Clip Content
<?php $this->endClip(); ?>

0 comments on commit a97757d

Please sign in to comment.