FAQ-OMatic

 view release on metacpan or  search on metacpan

lib/FAQ/OMatic/Item.pm  view on Meta::CPAN

			adjustDependencies('remove', $itemName, $self->{'filename'});
		}
		foreach $itemName (@addList) {
			adjustDependencies('insert', $itemName, $self->{'filename'});
		}
	}
}

sub getDependencies {
	my $filename = shift;
	my $depItem = loadDepItem($filename);
	return $depItem->getSet('HeDependsOnMe-Set')->getList();
}

sub loadDepItem {
	my $itemName = shift;

	my $depFile = "$itemName.dep";
	my $depItem = new FAQ::OMatic::Item($depFile,
			$FAQ::OMatic::Config::cacheDir);
	$depItem->setProperty('Title', 'Dependency List');
			# in case $depItem was new
	return $depItem;
}

sub adjustDependencies {
	my $what = shift;		# 'insert' or 'remove'
	my $itemName = shift;
	my $targetName = shift;

	my $depItem = loadDepItem($itemName);
	my $hdos = $depItem->getSet('HeDependsOnMe-Set');
	if ($what eq 'insert') {
		$hdos->insert($targetName);
	} else {
		$hdos->remove($targetName);
	}
	$depItem->setProperty('HeDependsOnMe-Set', $hdos);
			# in case $hdos was new
	my $depFile = "$itemName.dep";
	$depItem->saveToFile($depFile,
			$FAQ::OMatic::Config::cacheDir);
}

# For explicit faqomatic: links, the dependency mechanism is automatic:
# the link can't change without the item itself changing, so when the
# item gets written out, the cache and dependencies for it are up-to-date.
#
# For parent links, the dependency mechanism still works -- if a parent
# moves or changes its name (or this item moves, which is an operation on
# its parent), the old parent had to get written, and this item knew it
# was dependent on that parent, so this item gets rewritten, too, and has
# its dependencies updated, at which point it detects any new parent.
#
# But for sibling links, this item has no way of discovering (via
# dependencies) when those links change. Whenever a category changes its
# directory part list, it has also changed the sibling links for some
# of its children. In any case like that, it's the parent's responsibility
# to rewrite all of its children, so their dependencies and caches
# can be recomputed.
sub updateAllChildren {
	my $self = shift;

	my $filei;
	foreach $filei ($self->getChildren()) {
		#FAQ::OMatic::gripe('debug', "Updating child $filei of ".$self->{'filename'});
		my $itemi = new FAQ::OMatic::Item($filei);
		if (not $itemi->isBroken()) {
	#		$itemi->writeCacheCopy();
	# jonh: only writing the cache copy isn't enough -- if $itemi's set of
	# siblings has changed, then its IDependOns have changed, too. Those
	# are stored in the item file itself.
			$itemi->saveToFile('', '', 'noChange');
				# The contents of the item itself haven't changed.
				# The 'noChange' prevents us from updating the LastModifiedSecs
				# property, so that this item doesn't show up in 'recent'
				# searches even though it hasn't actually changed.
		}
	}
}

sub getChildren {
	my $self = shift;

	my $dirPart = $self->getDirPart();
	if (defined($dirPart)) {
		return $dirPart->getChildren();
	}
	return ();
}

sub getBags {
	my $self = shift;

	# remove duplicates but keep order using a Set
	my $bagset = new FAQ::OMatic::Set('keepOrdered');
	my $i;
	for ($i=0; $i<$self->numParts(); $i++) {
		$bagset->insert($self->getPart($i)->getBags());
	}

	return $bagset->getList();
}

# Currently meaningful -Sets that can be in an Item:
# HeDependsOnMe-Set: list of items that depend on this item's Title property
# IDependOn-Set: list of items whose titles this item depends upon.
#	it's useful so we can revoke our membership in that item's
#	HeDependsOnMe-Set when we no longer refer to it.

sub getSet {
	my $self = shift;
	my $setName = shift;

	return $self->{$setName} || new FAQ::OMatic::Set;
}

sub writeCacheCopy {
	my $self = shift;

	my $filename = $self->{'filename'};

lib/FAQ/OMatic/Item.pm  view on Meta::CPAN

	$moderator = FAQ::OMatic::validEmail($moderator);
	if (defined($moderator)) {
		# send the mail to the moderator
		# pageHeader is added to tell which FAQ has sent the mail.  
		# THANKS suggested by Akiko Takano <takano@iij.ad.jp>
		FAQ::OMatic::sendEmail($moderator, 
			"[" . FAQ::OMatic::fomTitle() . "] " . $self->getTitle().":".$didWhat,
			$msg);
	} else {
		FAQ::OMatic::gripe('problem',
			"Moderator address is suspect ($moderator)");
	}
}

# item in the parent's list
sub getSiblings {
	my $self = shift;
	my ($prev, $next);

	my $parent = $self->getParent();
	return (undef,undef) if (not $parent);
	my @siblings = $parent->getChildren();
	my $i;
	for ($i=0; $i<@siblings; $i++) {
		if ($siblings[$i] eq $self->{'filename'}) {
			$prev = ($i>0) ? $siblings[$i-1] : undef;
			$next = ($i<@siblings-1) ? $siblings[$i+1] : undef;
			return ($prev,$next);
		}
	}
	return (undef,undef);
}

sub isCategory {
	my $self = shift;
	return (defined $self->{'directoryHint'}) ? 1 : 0;
}

# added for convenient reasons
sub isAnswer {
	my $self = shift;
	return !($self->isCategory());
}

sub whatAmI {
	# do not translate here; translate just before output.
	# (There is code that tests for string equality based on the
	# output of this function. Maybe that's stupid.)
	my $self = shift;

	return gettext_noop("Category")	if ($self->isCategory());
	return gettext_noop("Answer")	if ($self->isAnswer());

	# unreachable
	gripe('problem',
		  'Internal error #20010805-1843: unreachable code is reached',
		  1);
	return "(Unexpected item type)";
}

sub updateDirectoryHint {
	my $self = shift;

	my $i;
	for ($i=0; $i<$self->numParts(); $i++) {
		if ($self->getPart($i)->{'Type'} eq 'directory') {
			$self->{'directoryHint'} = $i;
			return;
		}
	}
	delete $self->{'directoryHint'};
}

sub clone {
	# return a deep-copy of myself
	my $self = shift;

	my $newitem = new FAQ::OMatic::Item();

	# copy all of prototype's attributes
	my $key;
	foreach $key (keys %{$self}) {
		next if ($key eq 'Parts');
		if ($key =~ m/-Set$/) {
			$newitem->{$key} = $self->{$key}->clone();
		} elsif (ref $self->{$key}) {
			# guarantee this is a deep copy -- if we missed
			# a ref, complain.
			FAQ::OMatic::gripe('error', "clone: prototype has key '$key' "
				."that is a reference (".$self->{$key}.").");
		}
		$newitem->{$key} = $self->{$key};
	}

	# copy all the parts...
	my $i;
	for ($i=0; $i<$self->numParts(); $i++) {
		push(@{$newitem->{'Parts'}}, $self->getPart($i)->clone());
	}

	$newitem->updateDirectoryHint();

	return $newitem;
}

sub checkSequence {
	my $self = shift;
	my $params = shift;

	my $checkSequenceNumber =
		defined($params->{'checkSequenceNumber'})
		? $params->{'checkSequenceNumber'}
		: -1;
	if ($checkSequenceNumber ne $self->{'SequenceNumber'}) {
		my $button = FAQ::OMatic::button(
			FAQ::OMatic::makeAref('-command'=>'faq',
				'-params'=>$params,
				'-changedParams'=>{'partnum'=>'', 'checkSequenceNumber'=>''}
			),
			gettext("Return to the FAQ"));
		FAQ::OMatic::gripe('error',



( run in 0.522 second using v1.01-cache-2.11-cpan-39bf76dae61 )