/** * Stores the tags to database * * @param eZContentObjectAttribute $attribute */ function store($attribute) { if (!($attribute instanceof eZContentObjectAttribute && is_numeric($attribute->attribute('id')))) { return; } $attributeID = $attribute->attribute('id'); $attributeVersion = $attribute->attribute('version'); $objectID = $attribute->attribute('contentobject_id'); $db = eZDB::instance(); $currentTime = time(); //get existing tags for object attribute $existingTagIDs = array(); $existingTags = $db->arrayQuery("SELECT DISTINCT keyword_id FROM eztags_attribute_link WHERE objectattribute_id = {$attributeID} AND objectattribute_version = {$attributeVersion}"); if (is_array($existingTags)) { foreach ($existingTags as $t) { $existingTagIDs[] = (int) $t['keyword_id']; } } //get tags to delete from object attribute $tagsToDelete = array(); $tempIDArray = array(); // if for some reason already existing tags are added with ID = 0 with fromString // check to see if they really exist, so we don't delete them by mistake foreach (array_keys($this->IDArray) as $key) { if ($this->IDArray[$key] == 0) { $existing = eZTagsObject::fetchList(array('keyword' => array('like', trim($this->KeywordArray[$key])), 'parent_id' => $this->ParentArray[$key])); if (is_array($existing) && !empty($existing)) { $tempIDArray[] = $existing[0]->attribute('id'); } } else { $tempIDArray[] = $this->IDArray[$key]; } } foreach ($existingTagIDs as $tid) { if (!in_array($tid, $tempIDArray)) { $tagsToDelete[] = $tid; } } //and delete them if (!empty($tagsToDelete)) { $dbString = $db->generateSQLINStatement($tagsToDelete, 'keyword_id', false, true, 'int'); $db->query("DELETE FROM eztags_attribute_link WHERE {$dbString} AND eztags_attribute_link.objectattribute_id = {$attributeID} AND eztags_attribute_link.objectattribute_version = {$attributeVersion}"); } //get tags that are new to the object attribute $newTags = array(); $tagsToLink = array(); foreach (array_keys($this->IDArray) as $key) { if (!in_array($this->IDArray[$key], $existingTagIDs)) { if ($this->IDArray[$key] == 0) { // We won't allow adding tags to the database that already exist, but instead, we link to the existing tags $existing = eZTagsObject::fetchList(array('keyword' => array('like', trim($this->KeywordArray[$key])), 'parent_id' => $this->ParentArray[$key])); if (is_array($existing) && !empty($existing)) { if (!in_array($existing[0]->attribute('id'), $existingTagIDs)) { $tagsToLink[] = $existing[0]->attribute('id'); } } else { $newTags[] = array('id' => $this->IDArray[$key], 'keyword' => $this->KeywordArray[$key], 'parent_id' => $this->ParentArray[$key]); } } else { $tagsToLink[] = $this->IDArray[$key]; } } } //we need to check if user really has access to tags/add, taking into account policy and subtree limits $attributeSubTreeLimit = $attribute->contentClassAttribute()->attribute(eZTagsType::SUBTREE_LIMIT_FIELD); $userLimitations = eZTagsTemplateFunctions::getSimplifiedUserAccess('tags', 'add'); if ($userLimitations['accessWord'] != 'no' && !empty($newTags)) { //first we need to fetch all locations user has access to $userLimitations = isset($userLimitations['simplifiedLimitations']['Tag']) ? $userLimitations['simplifiedLimitations']['Tag'] : array(); $allowedLocations = self::getAllowedLocations($attributeSubTreeLimit, $userLimitations); foreach ($newTags as $t) { //and then for each tag check if user can save in one of the allowed locations $parentTag = eZTagsObject::fetch($t['parent_id']); $pathString = $parentTag instanceof eZTagsObject ? $parentTag->attribute('path_string') : '/'; $depth = $parentTag instanceof eZTagsObject ? (int) $parentTag->attribute('depth') + 1 : 1; if (self::canSave($pathString, $allowedLocations)) { $db->query("INSERT INTO eztags ( parent_id, main_tag_id, keyword, depth, path_string, modified, remote_id ) VALUES ( " . $t['parent_id'] . ", 0, '" . $db->escapeString(trim($t['keyword'])) . "', {$depth}, '{$pathString}', 0, '" . eZTagsObject::generateRemoteID() . "' )"); $tagID = (int) $db->lastSerialID('eztags', 'id'); $db->query("UPDATE eztags SET path_string = CONCAT(path_string, CAST({$tagID} AS CHAR), '/') WHERE id = {$tagID}"); $pathArray = explode('/', trim($pathString, '/')); array_push($pathArray, $tagID); $db->query("UPDATE eztags SET modified = {$currentTime} WHERE " . $db->generateSQLINStatement($pathArray, 'id', false, true, 'int')); $tagsToLink[] = $tagID; if (class_exists('ezpEvent', false)) { ezpEvent::getInstance()->filter('tag/add', array('tag' => eZTagsObject::fetch($tagID), 'parentTag' => $parentTag)); } } } } //link tags to objects taking into account subtree limit if (!empty($tagsToLink)) { $dbString = $db->generateSQLINStatement($tagsToLink, 'id', false, true, 'int'); $tagsToLink = $db->arrayQuery("SELECT id, path_string FROM eztags WHERE {$dbString}"); if (is_array($tagsToLink) && !empty($tagsToLink)) { foreach ($tagsToLink as $t) { if ($attributeSubTreeLimit == 0 || $attributeSubTreeLimit > 0 && strpos($t['path_string'], '/' . $attributeSubTreeLimit . '/') !== false) { $db->query("INSERT INTO eztags_attribute_link ( keyword_id, objectattribute_id, objectattribute_version, object_id ) VALUES ( " . $t['id'] . ", {$attributeID}, {$attributeVersion}, {$objectID} )"); } } } } }
$children = eZTagsObject::fetchList(array('parent_id' => $tagID, 'main_tag_id' => 0), $limitArray); $response = array(); $response['error_code'] = 0; $response['id'] = $tagID; $response['parent_id'] = $tag instanceof eZTagsObject ? (int) $tag->attribute('parent_id') : -1; $response['children_count'] = count($children); $response['children'] = array(); foreach ($children as $child) { $childResponse = array(); $childResponse['id'] = (int) $child->attribute('id'); $childResponse['parent_id'] = (int) $child->attribute('parent_id'); $childResponse['has_children'] = $child->getChildrenCount() > 0 ? 1 : 0; $childResponse['synonyms_count'] = $child->getSynonymsCount(); $childResponse['subtree_limitations_count'] = $child->getSubTreeLimitationsCount(); $childResponse['language_name_array'] = $child->languageNameArray(); $childResponse['keyword'] = $child->attribute('keyword'); $childResponse['url'] = 'tags/id/' . $child->attribute('id'); $childResponse['icon'] = eZTagsTemplateFunctions::getTagIcon($child->getIcon()); eZURI::transformURI($childResponse['url']); $childResponse['modified'] = (int) $child->attribute('modified'); $response['children'][] = $childResponse; } $jsonText = json_encode($response); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + MAX_AGE) . ' GMT'); header('Cache-Control: cache, max-age=' . MAX_AGE . ', post-check=' . MAX_AGE . ', pre-check=' . MAX_AGE); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $tag instanceof eZTagsObject ? (int) $tag->attribute('modified') : time()) . ' GMT'); header('Pragma: cache'); header('Content-Type: application/json'); header('Content-Length: ' . strlen($jsonText)); echo $jsonText; eZExecution::cleanExit();
if ($parentTagID > 0) { $parentTag = eZTagsObject::fetchWithMainTranslation($parentTagID); if (!$parentTag instanceof eZTagsObject) { return $Module->handleError(eZError::KERNEL_NOT_FOUND, 'kernel'); } if ($parentTag->attribute('main_tag_id') != 0) { return $Module->redirectToView('add', array($parentTag->attribute('main_tag_id'))); } } if ($http->hasPostVariable('DiscardButton')) { if ($parentTag instanceof eZTagsObject) { return $Module->redirectToView('id', array($parentTag->attribute('id'))); } return $Module->redirectToView('dashboard', array()); } $userLimitations = eZTagsTemplateFunctions::getSimplifiedUserAccess('tags', 'add'); $hasAccess = false; if (!isset($userLimitations['simplifiedLimitations']['Tag'])) { $hasAccess = true; } else { $parentTagPathString = $parentTag instanceof eZTagsObject ? $parentTag->attribute('path_string') : '/'; foreach ($userLimitations['simplifiedLimitations']['Tag'] as $key => $value) { if (strpos($parentTagPathString, '/' . $value . '/') !== false) { $hasAccess = true; break; } } } if (!$hasAccess) { return $Module->handleError(eZError::KERNEL_ACCESS_DENIED, 'kernel'); }
/** * Returns the array with permission info for linking tags to current content object attribute * * @return array */ private function getPermissionArray() { $permissionArray = array('can_add' => false, 'subtree_limit' => $this->Attribute->contentClassAttribute()->attribute(eZTagsType::SUBTREE_LIMIT_FIELD), 'allowed_locations' => array(), 'allowed_locations_tags' => false); $userLimitations = eZTagsTemplateFunctions::getSimplifiedUserAccess('tags', 'add'); if ($userLimitations['accessWord'] == 'no') { return $permissionArray; } $userLimitations = isset($userLimitations['simplifiedLimitations']['Tag']) ? $userLimitations['simplifiedLimitations']['Tag'] : array(); $limitTag = eZTagsObject::fetchWithMainTranslation($permissionArray['subtree_limit']); if (empty($userLimitations)) { if ($permissionArray['subtree_limit'] == 0 || $limitTag instanceof eZTagsObject) { $permissionArray['allowed_locations'] = array($permissionArray['subtree_limit']); if ($limitTag instanceof eZTagsObject) { $permissionArray['allowed_locations_tags'] = array($limitTag); } } } else { if ($permissionArray['subtree_limit'] == 0) { $permissionArray['allowed_locations_tags'] = array(); /** @var eZTagsObject[] $userLimitations */ $userLimitations = eZTagsObject::fetchList(array('id' => array($userLimitations)), null, null, true); if (is_array($userLimitations) && !empty($userLimitations)) { foreach ($userLimitations as $limitation) { $permissionArray['allowed_locations'][] = $limitation->attribute('id'); $permissionArray['allowed_locations_tags'][] = $limitation; } } } else { if ($limitTag instanceof eZTagsObject) { /** @var eZTagsObject[] $userLimitations */ $userLimitations = eZTagsObject::fetchList(array('id' => array($userLimitations)), null, null, true); if (is_array($userLimitations) && !empty($userLimitations)) { $pathString = $limitTag->attribute('path_string'); foreach ($userLimitations as $limitation) { if (strpos($pathString, '/' . $limitation->attribute('id') . '/') !== false) { $permissionArray['allowed_locations'] = array($permissionArray['subtree_limit']); $permissionArray['allowed_locations_tags'] = array($limitTag); break; } } } } } } if (!empty($permissionArray['allowed_locations'])) { $permissionArray['can_add'] = true; } return $permissionArray; }