Files
server/usr/share/psa-horde/imp/lib/Ftree/Eltdiff.php
2026-01-07 20:52:11 +01:00

219 lines
5.4 KiB
PHP

<?php
/**
* Copyright 2013-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* did not receive this file, see http://www.horde.org/licenses/gpl.
*
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*/
/**
* Track element changes in the folder tree.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2013-2017 Horde LLC
* @license http://www.horde.org/licenses/gpl GPL
* @package IMP
*
* @method void add(string $elt) Element added to tree.
* @method void change(string $elt) Element changed in tree.
* @method void delete(string $elt) Element deleted in tree.
*
* @property-read array $add List of added elements.
* @property-read array $change List of changed elements.
* @property-read integer $changed_elts The number of changed elements
* tracked.
* @property-read array $delete List of deleted elements.
* @property boolean $track Is tracking active?
*/
class IMP_Ftree_Eltdiff implements Serializable
{
/* Constants for $_changes values. */
const ADD = 1;
const CHANGE = 2;
const DELETE = 4;
const EXIST = 8;
/**
* Has the internal data structure changed?
*
* @var boolean
*/
public $changed = false;
/**
* List of diffs.
*
* @var array
*/
protected $_changes = array();
/**
* Is tracking active?
*
* @var boolean
*/
protected $_track = false;
/**
*/
public function __call($name, $args)
{
switch ($name) {
case 'add':
case 'change':
case 'delete':
if ($this->track) {
$elt = reset($args);
/* Don't track base element. */
if ($elt instanceof IMP_Ftree_Element) {
if ($elt->base_elt) {
return;
}
} elseif (!strlen($elt)) {
return;
}
$elt = strval($elt);
$value = isset($this->_changes[$elt])
? $this->_changes[$elt]
: null;
switch ($name) {
case 'add':
if (is_null($value)) {
$value = self::ADD;
} elseif ($value & self::EXIST) {
$value = self::CHANGE | self::EXIST;
} else {
$value &= ~self::CHANGE & ~self::DELETE;
$value |= self::ADD;
}
break;
case 'change':
if (is_null($value)) {
$value = self::CHANGE | self::EXIST;
} elseif (($value & self::EXIST) ||
!($value & self::ADD)) {
$value &= ~self::ADD & ~self::DELETE;
$value |= self::CHANGE;
}
break;
case 'delete':
if (is_null($value)) {
$value = self::DELETE | self::EXIST;
} else {
$value &= ~self::ADD & ~self::CHANGE;
$value |= self::DELETE;
}
break;
}
$this->_changes[$elt] = $value;
}
break;
}
}
/**
*/
public function __get($name)
{
switch ($name) {
case 'add':
case 'change':
case 'delete':
switch ($name) {
case 'add':
$mask = self::ADD;
break;
case 'change':
$mask = self::CHANGE;
break;
case 'delete':
$mask = self::DELETE;
break;
}
$out = array();
foreach ($this->_changes as $key => $val) {
if ($val & $mask) {
$out[] = $key;
}
}
return $out;
case 'changed_elts':
return count($this->_changes);
case 'track':
return $this->_track;
}
}
/**
*/
public function __set($name, $value)
{
switch ($name) {
case 'track':
$value = (bool)$value;
if ($value != $this->_track) {
$this->_track = $value;
$this->changed = true;
}
break;
}
}
/**
* Clear diff stats.
*/
public function clear()
{
if (!empty($this->_changes)) {
$this->_changes = array();
$this->changed = true;
}
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return $GLOBALS['injector']->getInstance('Horde_Pack')->pack(
array(
$this->track,
$this->_changes
),
array(
'compression' => false,
'phpob' => false
)
);
}
/**
*/
public function unserialize($data)
{
list(
$this->track,
$this->_changes
) = $GLOBALS['injector']->getInstance('Horde_Pack')->unpack($data);
}
}