heimrichhannot/contao-observer

contao的观察器。

1.2.0 2018-01-25 13:24 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:36:46 UTC


README

contao的观察器。目前它被heimrichhannot/contao-collab所依赖,可以从邮箱创建任务或通知任务分配者。但它很容易扩展。

特性

观察器是一个定时任务模块,它检查主题是否符合给定的标准,并更新附加的观察器。其结构基于观察者模式。例如,我们有像邮箱这样的主题。如果接收到符合给定标准(例如新邮件)的邮件,则附加的Taskobserver将从给定的邮件中创建一个新的任务(heimrichhannot/contao-collab所依赖)。

  • 观察邮箱(需要php-imap扩展)
  • 等待主题年龄(等待直到上下文的tstamp过期给定的等待时间)
  • 优先级处理(管理执行顺序)
  • 观察器日志
  • 观察器历史:在本地历史中存储所有已运行的主题/观察器组合(例如,将防止多次用户通知)

观察器管理器

观察器管理器观察分时contao定时任务中的所有实体。它可以在开箱即用的分时定时任务中工作,或者您可以在crontab中调用二进制脚本。

Contao 3(不使用composer)

* * * * * php /path/to/contao/system/modules/observer/bin/manager.php

Contao 3(使用composer)

* * * * * php /path/to/contao/composer/vendor/heimrichhannot/contao-observer/bin/manager.php

Contao 4

* * * * * php /path/to/contao/vendor/heimrichhannot/contao-observer/bin/manager.php

在您的自定义模块中使用

添加新的主题

主题可以是邮箱,或者特定任务列表中的任务,具有所需的条件(未阅读的邮件、未分配的任务...)。

1. 将主题添加到config.php
// config.php
array_insert(
	$GLOBALS['OBSERVER']['SUBJECTS'],
	0,
	[
		'MY_SUBJECT_NAME' => 'MyNamespace\Observer\MySubject',
	]
);
2. 将您的主题配置添加到tl_observer.php

您也可以在这里添加自定义字段。

// tl_observer.php

$arrDca = &$GLOBALS['TL_DCA']['tl_observer'];

/**
 * Palettes
 */
$arrDca['palettes']['MY_SUBJECT_NAME'] =
	'{general_legend},subject,title;{cronjob_legend},cronInterval,useCronExpression,priority,invoked,invokedState;{observer_legend},observer;{expert_legend},debug,addObserverStates;{publish_legend},published;';
3. 创建您的主题对象'MyNamespace\Observer\MySubject'

必须扩展HeimrichHannot\Observer\Subject

<?php
/**
 * Contao Open Source CMS
 *
 * Copyright (c) 2016 Heimrich & Hannot GmbH
 *
 * @author  Rico Kaltofen <r.kaltofen@heimrich-hannot.de>
 * @license https://gnu.ac.cn/licences/lgpl-3.0.html LGPL
 */

namespace MyNamespace\Observer;

use HeimrichHannot\Observer\ObserverLog;
use HeimrichHannot\Observer\Subject;

class TaskSubject extends Subject
{
	/**
	 * Run your subject observer
	 *
	 * @return bool True on success, false on error
	 */
	public function notify()
	{
		$arrLists    = deserialize($this->getObserver()->tasklists, true);
		$arrCriteria = deserialize($this->getObserver()->taskCriteria, true);

		$objTasks = TaskModel::findByListsAndCriteria($arrLists, $arrCriteria);

		if ($objTasks === null)
		{
			if ($this->getObserver()->debug)
			{
				ObserverLog::add($this->getObserver()->id, 'No tasks for given filter found.', __CLASS__ . ':' . __METHOD__);
			}

			return;
		}

		if ($this->getObserver()->debug)
		{
			$count = $objTasks->count();
			ObserverLog::add($this->getObserver()->id, $count . ($count == 1 ? ' Task' : ' Tasks') . ' found for given filter.', __CLASS__ . ':' . __METHOD__);
		}

		while ($objTasks->next())
		{
			$this->context = $objTasks->current();

			if (!$this->waitForContext($this->context))
			{
				if ($this->getObserver()->debug)
				{
					ObserverLog::add($this->getObserver()->id, 'Observers updated with task: "' . $objTasks->title . '" [ID:' . $objTasks->id .  '].', __CLASS__ . ':' . __METHOD__);
				}

				foreach ($this->observers as $obs)
				{
					$obs->update($this);
				}

				continue;
			}

			if ($this->getObserver()->debug)
			{
				ObserverLog::add($this->getObserver()->id, 'Waiting time for task: "' . $objTasks->title . '" [ID:' . $objTasks->id .  '] not elapsed yet.', __CLASS__ . ':' . __METHOD__);
			}
		}

		return true;
	}
}

添加新的观察器

观察器例如是将发送给给定成员(例如任务分配者)的通知,当找到具有给定标准的主题时。

1. 将观察器添加到config.php
// config.php
array_insert(
	$GLOBALS['OBSERVER']['OBSERVERS'],
	0,
	[
		'MY_OBSERVER_NAME' => 'MyNamespace\Observer\MyObserver',
	]
);
2. 创建您的观察器对象'MyNamespace\Observer\MyObserver'

必须扩展HeimrichHannot\Observer\Observer

<?php
/**
 * Contao Open Source CMS
 *
 * Copyright (c) 2016 Heimrich & Hannot GmbH
 *
 * @author  Rico Kaltofen <r.kaltofen@heimrich-hannot.de>
 * @license https://gnu.ac.cn/licences/lgpl-3.0.html LGPL
 */

namespace HeimrichHannot\Collab\Observer;


use HeimrichHannot\Collab\CollabConfig;
use HeimrichHannot\Collab\Helper\TaskHelper;
use HeimrichHannot\Haste\Model\Model;
use HeimrichHannot\Observer\NotificationObserver;
use HeimrichHannot\Observer\Observer;
use HeimrichHannot\Observer\ObserverNotification;
use HeimrichHannot\Versions\VersionModel;

class TaskNotificationObserver extends NotificationObserver
{
    // optionally define new states for your observer
    const STATE_EXISTING = 'existing';
    
    const STATES = [
        self::STATE_SUCCESS,
        self::STATE_EXISTING,
        self::STATE_ERROR
    ];
    
	protected function createNotification()
	{
		ObserverNotification::sendNotification(
			$this->objSubject->getObserver()->notification,
			$this->objSubject->getObserver(),
			$this->objSubject->getContext(),
			$this->getMember()
		);

		// as mails might sent from queue it is not possible to determine if there were mail errors
		return Observer::STATE_SUCCESS;
	}

	protected function getEntityId()
	{
		// Add the version to the entity id, as we build on versions
		$objVersion = VersionModel::findCurrentByModel($this->getSubject()->getContext());

		return sprintf(
			'%s_%s:%s_%s:%s_%s',
			$this->getSubject()->getContext()->getTable(),
			$this->getSubject()->getContext()->id,
			$this->getMember()->getTable(),
			$this->getMember()->id,
			'tl_version',
			$objVersion === null ? '0' : $objVersion->id
		);

	}

	/**
	 * Modify members
	 *
	 * @param \Model\Collection|null $objMembers
	 *
	 * @return \Model\Collection|null Return the collection of member entities or null
	 */
	protected function modifyMembers($objMembers = null)
	{
		// notify if assigneeType is member and authorType is not user and author != assignee
		if ($this->getSubject()->getContext()->assigneeType == CollabConfig::AUTHOR_TYPE_MEMBER)
		{
			$objAuthor = TaskHelper::getCurrentAuthor($this->getSubject()->getContext());
			$objAssignee = TaskHelper::getCurrentAssignee($this->getSubject()->getContext());

			// add current assignee
			if ($this->getSubject()->getObserver()->notifyAssignee && $objAssignee !== null)
			{
				// skip if author is assignee
				if ($objAuthor->id != $objAssignee->id)
				{
					$objMembers = Model::addModelToCollection($objAssignee, $objMembers);
				}
			}

			// add previous assignee
			if($this->getSubject()->getObserver()->notifyPreviousAssignee)
			{
				if (($objPreviousAssignee = TaskHelper::getPreviousAssignee($this->getSubject()->getContext())) !== null)
				{
					$objMembers = Model::addModelToCollection($objPreviousAssignee, $objMembers);
				}
			}

			// remove current assignee
			if($this->getSubject()->getObserver()->skipNotifyAssignee && $objAssignee !== null)
			{
				$objMembers = Model::removeModelFromCollection($objAssignee, $objMembers);
			}

			// remove previous assignee
			if($this->getSubject()->getObserver()->skipNotifyPreviousAssignee)
			{
				if (($objPreviousAssignee = TaskHelper::getPreviousAssignee($this->getSubject()->getContext())) !== null)
				{
					$objMembers = Model::removeModelFromCollection($objPreviousAssignee, $objMembers);
				}
			}
		}

		return $objMembers;
	}

    // optional
	public static function getPalettes(\DataContainer $dc = null)
	{
		return [
			CollabConfig::OBSERVER_SUBJECT_TASK => 'notification,notifyAssignee,notifyPreviousAssignee,members,memberGroups,limitMembers,skipNotifyAssignee,skipNotifyPreviousAssignee',
		];
	}


}

getPalettes方法是必需的,以使观察器与多个给定主题相关联。数组对的键必须是主题名称,值应包含应添加到给定主题配置的tl_observer.php配置(在观察器选择下拉菜单之后)的所有字段。