public function saveInTags(DatabaseInterface $db, NodeRef $originNodeRef, $recordid, $inPartials = 'fields', array $inTags, $restrictedPartials = '')
 {
     if (empty($recordid)) {
         throw new Exception('Cannot save in tags without recordid');
     }
     TagUtils::validateTags($inTags);
     $originalRestrictedPartials = $restrictedPartials;
     $restrictedPartials = PartialUtils::unserializeInPartials($restrictedPartials);
     if ($restrictedPartials == 'all' || ($x = array_search('all', $restrictedPartials)) !== false) {
         return false;
     }
     //        $originNodeRef = $node->getNodeRef();
     //        $outtable = $this->NodeDBMeta->getOutTagsTable($originNodeRef);
     $intable = $this->NodeDBMeta->getInTagsTable($originNodeRef);
     $tableid = $this->NodeDBMeta->getPrimaryKey($originNodeRef);
     //        $now = $this->DateFactory->newStorageDate();
     //        $schema = $originNodeRef->getElement()->getSchema();
     $tagsToDelete = array();
     $tagsToUpdate = array();
     // remove duplicates from tags
     foreach ($inTags as $o => $tag) {
         if ($originNodeRef->getElement()->hasTagDef($tag->getTagRole())) {
             $tagDef = $originNodeRef->getElement()->getSchema()->getTagDef($tag->getTagRole());
         } else {
             $externalElement = $this->ElementService->getBySlug($tag->getTagElement());
             $tagDef = $externalElement->getSchema()->getTagDef($tag->getTagRole());
         }
         $tag->MatchPartial = TagUtils::determineMatchPartial($tagDef, $originNodeRef->getSlug());
         $this->Logger->debug('MATCH PARTIAL for [' . $tag->toString() . '] is [' . $tag->MatchPartial->toString() . ']');
         if (!$tagDef->isSortable()) {
             $tag->TagSortOrder = 0;
         } else {
             $tag->ShouldMatchSort = true;
         }
         foreach ($inTags as $i => $dtag) {
             if ($o != $i && $tag->matchExact($dtag)) {
                 //                  error_log("REMOVING DUPE ".$dtag->toString());
                 unset($inTags[$o]);
             }
         }
         foreach ($restrictedPartials as $partial) {
             if ($this->TagsHelper->matchPartial($partial, $tag)) {
                 unset($inTags[$o]);
             }
         }
     }
     $currentInTags = $this->findTags('in', $db, $originNodeRef, $recordid, $inPartials, true, false, $originalRestrictedPartials, $resolveLinkedRecords = false);
     TagUtils::validateTags($currentInTags, 'in');
     foreach ($currentInTags as $k => $tag) {
         //if($tag->getTagOutID() == false) throw new Exception('Cannot save in tags without TagOutIDs for current tags');
         $foundThisTag = false;
         foreach ($inTags as $k2 => $dtag) {
             // Get a list of fields that differ between the current tag and the tag to be saved
             $tagDiff = $tag->diff($dtag, $dtag->ShouldMatchSort);
             if (empty($tagDiff)) {
                 // remove it from inTags, since it exists already
                 unset($inTags[$k2]);
                 $foundThisTag = true;
                 break;
             } elseif (count($tagDiff) == 1 && $tagDiff[0] == 'TagSortOrder') {
                 // If the only difference between the tags is sort order, we don't
                 // want to remove the tag and then add it back. Just do an update.
                 // Save the tag to run through updates later.
                 $tag->setTagSortOrder($dtag->getTagSortOrder());
                 $tagsToUpdate[] = $tag;
                 // Remove it from intags because we don't want it added again
                 unset($inTags[$k2]);
                 $foundThisTag = true;
                 break;
             }
         }
         if (!$foundThisTag) {
             $tagsToDelete[] = $tag;
         }
     }
     if (empty($tagsToDelete) && empty($inTags) && empty($tagsToUpdate)) {
         return false;
     }
     foreach ($tagsToDelete as $tag) {
         $this->Logger->debug("Delete {$tag->getTagDirection()} tag: {$tag->toString()}");
         // delete corresponding out tag
         $outElement = $this->ElementService->getBySlug($tag->getTagElement());
         $outNodeRef = new NodeRef($outElement, $tag->getTagSlug());
         $outtable = $this->NodeDBMeta->getOutTagsTable($outNodeRef);
         $outtableid = $this->NodeDBMeta->getPrimaryKey($outNodeRef);
         try {
             $outrecordid = $this->getRecordIDFromNodeRef($outNodeRef);
         } catch (NodeException $ne) {
             continue;
         }
         $affectedRows = $this->getConnectionForWrite($outNodeRef)->write("\n                DELETE FROM {$db->quoteIdentifier($outtable)} WHERE\n                    {$outtableid} = {$db->quote($outrecordid)} AND\n                    ElementID = {$db->quote($originNodeRef->getElement()->getElementID())} AND\n                    Slug = {$db->quote($originNodeRef->getSlug())} AND\n                    Role = {$db->quote($tag->getTagRole())} AND\n                    Value = {$db->quote($tag->getTagValue())}", DatabaseInterface::AFFECTED_ROWS);
         if ($affectedRows > 0) {
             $this->NodeEvents->fireTagEvents('outtags', 'remove', $outNodeRef, $originNodeRef, $tag);
         }
         $affectedRows = $db->deleteRecord($db->quoteIdentifier($intable), "TagID = {$db->quote($tag['TagID'])}");
         if ($affectedRows > 0) {
             $this->NodeEvents->fireTagEvents('intags', 'remove', $originNodeRef, $outNodeRef, $tag);
         }
     }
     // Tags that only have their sort order changed, do an update on both sides of the tag and fire an sortOrder.edit
     // event for the side of the tag that is ordered.
     foreach ($tagsToUpdate as $tag) {
         $this->Logger->debug("Update {$tag->getTagDirection()} tag: {$tag->toString()}");
         // update corresponding out tag
         $outNodeRef = $tag->TagLinkNodeRef;
         $outtable = $this->NodeDBMeta->getOutTagsTable($outNodeRef);
         $outtableid = $this->NodeDBMeta->getPrimaryKey($outNodeRef);
         try {
             $outrecordid = $this->getRecordIDFromNodeRef($outNodeRef);
         } catch (NodeException $ne) {
             continue;
         }
         $updateArray = array('SortOrder' => $tag->getTagSortOrder());
         $affectedRows = $db->updateRecord($db->quoteIdentifier($outtable), $updateArray, "{$outtableid} = {$db->quote($outrecordid)} AND\n                ElementID = {$db->quote($originNodeRef->getElement()->getElementID())} AND\n                Slug = {$db->quote($originNodeRef->getSlug())} AND\n                Role = {$db->quote($tag->getTagRole())} AND\n                Value = {$db->quote($tag->getTagValue())}");
         $affectedRows = $db->updateRecord($db->quoteIdentifier($intable), $updateArray, "TagID = {$db->quote($tag['TagID'])}");
         if ($affectedRows > 0) {
             $this->NodeEvents->fireTagEvents('intags', 'sortOrder.edit', $originNodeRef, $outNodeRef, $tag);
         }
     }
     if (!empty($inTags)) {
         foreach ($inTags as $inTag) {
             //                if($inTag->getTagSectionID() != 0)
             //                    throw new NodeException('Cannot save in tags coming from a section');
             $externalElement = $this->ElementService->getBySlug($inTag->getTagElement());
             $externalNodeRef = new NodeRef($externalElement, $inTag->getTagSlug());
             try {
                 $externalRecordID = $this->getRecordIDFromNodeRef($externalNodeRef);
             } catch (NodeException $ne) {
                 continue;
             }
             if ('' . $externalNodeRef == '' . $originNodeRef) {
                 continue;
             }
             $this->Logger->debug("Add {$inTag->getTagDirection()} tag: {$inTag->toString()}");
             //$inTagPartial = new TagPartial($inTag);
             $db = $this->getConnectionForWrite($externalNodeRef);
             $newTag = new Tag($originNodeRef->getElement()->getSlug(), $originNodeRef->getSlug(), $inTag->getTagRole(), $inTag->getTagValue(), $inTag->getTagValueDisplay());
             $newTag->setTagSortOrder($inTag->getTagSortOrder());
             // match partial is used to guarantee that only 1 outbound link exists for that element or element/value combo
             $this->saveOutTags($db, $externalNodeRef, $externalRecordID, $inTag->getMatchPartial()->toString(), array($newTag));
         }
     }
     return true;
 }
Exemple #2
0
 public function setOutTags(array $tags)
 {
     TagUtils::validateTags($tags, 'out');
     $this->fields['OutTags'] = $tags;
     unset($tags);
 }