Skip to content

Instantly share code, notes, and snippets.

@sbreker
Last active December 19, 2018 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sbreker/9870b86c9a980658dbbc9b7e9a3b1287 to your computer and use it in GitHub Desktop.
Save sbreker/9870b86c9a980658dbbc9b7e9a3b1287 to your computer and use it in GitHub Desktop.
Creator Unlinker: updates cases where a creator could be linked to io using inheritance.
<?php
// VERSION: 1.1
// Creator Unlinker: updates cases where a creator could be linked to io using inheritance.
// ACTOR/DESCR WILL BE OPTIONAL PARAMS TO CLI TASK
// - I have not tested setting both of these at the same time - not sure if that combo is useful.
// - If a descr slug is specified, all creators on this node + descendants will be examined.
// - If an actor slug is specified, all descrs with this creator will be examined.
// - only this actor can be modified.
// - in cases where more than one creator would have been unlinked, nothing will be done.
// - if actor or descr is NOT specified, all nodes will be examined to see if creators could be
// inherited instead.
//$actorSlug = "saunders-henry-1837-1904-family";
//$descrSlug = "henry-saunders-family-fonds";
// Get actor records from slug if supplied.
if (null !== $actorSlug)
{
$criteria = new Criteria;
$criteria->addJoin(QubitActor::ID, QubitSlug::OBJECT_ID);
$criteria->add(QubitSlug::SLUG, $actorSlug);
$actor = QubitActor::getOne($criteria);
if (null === $actor)
{
throw new Exception("Actor slug supplied but not found");
}
}
// Get IO from slug if supplied.
if (null !== $descrSlug)
{
$criteria = new Criteria;
$criteria->addJoin(QubitInformationObject::ID, QubitSlug::OBJECT_ID);
$criteria->add(QubitSlug::SLUG, $descrSlug);
$io = QubitInformationObject::getOne($criteria);
if (null === $io)
{
throw new Exception("Description slug supplied but not found");
}
// If IO supplied get list of descendant IO's, including self.
// We need ALL descendants because we are fixing all Creators for this IO.
foreach ($io->descendants->andSelf()->orderBy('lft') as $item)
{
$ioList[] = $item->id;
}
}
// Get affected io records via event table.
$criteria = new Criteria;
$criteria->addJoin(QubitInformationObject::ID, QubitEvent::OBJECT_ID);
$criteria->addJoin(QubitActor::ID, QubitEvent::ACTOR_ID);
$criteria->addGroupByColumn(QubitInformationObject::ID);
// limit to a specific actor
if (null !== $actor)
{
$criteria->add(QubitActor::ID, $actor->id, Criteria::EQUAL);
}
// limit to specific information object hierarchy
if (null !== $io)
{
$criteria->add(QubitInformationObject::ID, $ioList, Criteria::IN);
}
// Loop over hierarchy of this Information Object from the top down.
// Higher levels of IO must be fixed before lower nodes.
foreach (QubitInformationObject::get($criteria)->orderBy('lft') as $io)
{
$deleteCreators = false;
$creatorIds = array();
$ancestorCreatorIds = array();
printf("\nINFO OBJ: %s %d\n", $io->slug, $io->id);
// Nothing to do if this is the top level record.
if ($io->parentId == QubitInformationObject::ROOT_ID)
{
continue;
}
$creators = $io->getCreators();
foreach ($creators as $creator)
{
$creatorIds[] = $creator->id;
}
// Nothing to do if no creators on this IO.
if (0 == count($creatorIds))
{
continue;
}
// If an actor was specified as params, that is the only actor we can remove.
// If there is more than one actor on this IO, we can't remove only one or the inheritance
// will not work properly.
if (null !== $actor && 1 < count($creatorIds))
{
continue;
}
// Get all ancestors of this IO and iterate from bottom up.
foreach ($io->ancestors->andSelf()->orderBy('rgt') as $ancestor)
{
// if this ancestor is the root IO or self, skip it.
if ($ancestor->id == QubitInformationObject::ROOT_ID || $ancestor->id == $io->id)
{
continue;
}
$ancestorCreators = $ancestor->getCreators();
printf(" ANCESTOR: %s\n", $ancestor->slug);
// Creator list must match exactly. Test count, and if equal, then look closer
if (count($ancestorCreators) == count($creators))
{
foreach ($ancestorCreators as $ancestorCreator)
{
// Build ID array
$ancestorCreatorIds[] = $ancestorCreator->id;
}
$diff = array_diff($creatorIds, $ancestorCreatorIds);
// if the creator lists match exactly, then delete and inherit from ancestor.
if (0 == count($diff))
{
$deleteCreators = true;
break;
}
// If there are creators on the ancestors but they don't match:
// -- stop looking cause it does not matter what is above this node
// -- do not delete any creators because they do not match current ancestor.
else
{
break;
}
}
// If there are creators on the ancestors but they don't match:
// -- stop looking cause it does not matter what is above this node
// -- do not delete any creators because they do not match current ancestor.
else if (0 < count($ancestorCreators))
{
break;
}
}
if ($deleteCreators)
{
// This will unlink this Actor from all creation events on this IO.
foreach ($io->getActorEvents(array('eventTypeId' => QubitTerm::CREATION_ID)) as $event)
{
if (in_array($event->actor->id, $creatorIds))
{
printf(" REMOVING ACTOR\n");
$event->indexOnSave = true;
unset($event->actor);
$event->save();
// Delete the event record too if there aren't any dates/times on it.
if (null == $event->getPlace()->name && null == $event->date && null == $event->name && null == $event->description && null == $event->startDate && null == $event->endDate && null == $event->startTime && null == $event->endTime)
{
//event/actions/editComponent.class.php
$event->delete();
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment