public function addAction()
 {
     $data = $_POST;
     $destination = HTMLPurifier::getInstance()->purify(trim($data['path']));
     $form = $this->_getForm();
     $valid = $form->isValid($this->getRequest()->getPost());
     if (!$valid) {
         $taggingSession = new Zend_Session_Namespace('tagging');
         $taggingSession->post = serialize($_POST);
         $this->_helper->redirector->gotoUrl($destination . '#tagging-form');
     }
     // Currently, tags are allowed only on items.
     if (HTMLPurifier::getInstance()->purify(trim($data['record_type'])) != 'Item') {
         $this->_helper->flashMessenger(__('This record does not accept tags.'), 'warning');
         $this->_helper->redirector->gotoUrl($destination);
     }
     // Security check.
     $record = get_record_by_id(HTMLPurifier::getInstance()->purify(trim($data['record_type'])), (int) HTMLPurifier::getInstance()->purify(trim($data['record_id'])));
     if (!$record) {
         $this->_helper->flashMessenger(__('Record does not exist.'), 'warning');
         $this->_helper->redirector->gotoUrl($destination);
     }
     // Moderation or not.
     $user = current_user();
     // If the user can moderate, the proposition is automatically approved.
     $moderationRoles = unserialize(get_option('tagging_moderate_roles'));
     if (in_array($user->role, $moderationRoles)) {
         $status = 'approved';
     } else {
         if (empty($user)) {
             $user_id = 0;
             $requireModeration = (bool) get_option('tagging_public_require_moderation');
         } else {
             $user_id = $user->id;
             $requireModerationRoles = unserialize(get_option('tagging_require_moderation_roles'));
             $requireModeration = in_array($user->role, $requireModerationRoles);
         }
         $status = $requireModeration ? 'proposed' : 'allowed';
     }
     // Default values for tagging.
     $data['ip'] = $_SERVER['REMOTE_ADDR'];
     $data['user_agent'] = $_SERVER['HTTP_USER_AGENT'];
     $data['status'] = $status;
     // Need getValue to run the filter.
     $userTagging = HTMLPurifier::getInstance()->purify(trim($form->getElement('tagging')->getValue()));
     $proposedTaggingsNames = explode(get_option('tag_delimiter'), $userTagging);
     // Prepare checks of existing tags.
     $db = get_db();
     $recordTags = $record->getTags();
     $recordTaggings = $db->getTable('Tagging')->findByRecord($record);
     $recordTagsNames = $this->_getTagsNames($recordTags);
     $recordTaggingsNames = $this->_getTagsNames($recordTaggings);
     // There is one tagging by tag to simplify management.
     $tagsToAdd = array();
     $approvedExistingTags = array();
     foreach ($proposedTaggingsNames as $proposedTag) {
         $data['name'] = $proposedTag;
         $tagging = new Tagging();
         $tagging->user_id = $user_id;
         $tagging->setArray($data);
         $sanitizedName = $tagging->sanitizeName();
         // Check the quality of tag.
         if (!$sanitizedName) {
             continue;
         }
         // Check if this tagging is not a duplicate.
         if (in_array($sanitizedName, $tagsToAdd)) {
             continue;
         }
         // Check if this tagging is not already set.
         if (in_array($sanitizedName, $recordTagsNames)) {
             continue;
         }
         // Check size of a tag.
         if (strlen($sanitizedName) > get_option('tagging_max_length_tag')) {
             $this->_helper->flashMessenger(__('Individual tags can\'t be longer than %d characters.', get_option('tagging_max_length_tag')), 'error');
             continue;
         }
         // Check if this tagging is not already saved.
         if (in_array($sanitizedName, $recordTaggingsNames)) {
             $existingTagging = $recordTaggings[array_search($sanitizedName, $recordTaggingsNames)];
             // Check status.
             // Normally, an existing approved tagging is already an item tag.
             if ($tagging->status == 'approved') {
                 $existingTagging->status = 'approved';
                 try {
                     $existingTagging->save();
                 } catch (Exception $e) {
                     _log($e->getMessage());
                 }
                 $approvedExistingTags[] = $sanitizedName;
             }
             // In all other cases (already approved or rejected), the
             // old tagging is kept in place of the new one.
             continue;
         }
         $tagsToAdd[] = $sanitizedName;
         // Taggings are automatically added to item if they are appoved.
         try {
             $tagging->save();
         } catch (Exception $e) {
             _log($e->getMessage());
         }
     }
     // Information for user.
     if (count($approvedExistingTags)) {
         $this->_helper->flashMessenger(__('Your tags "%s" have been approved.', implode(', ', $approvedExistingTags)), 'success');
     }
     if (count($tagsToAdd) == 0 && count($approvedExistingTags) == 0) {
         $this->_helper->flashMessenger(__('This tag has already been submitted "%s" or it is not correctly formatted.', $userTagging), 'warning');
     } else {
         if ($requireModeration) {
             $this->_helper->flashMessenger(__('Your tag "%s" is awaiting approval', $userTagging), 'success');
         } else {
             if (count($tagsToAdd) == 0) {
                 // In that case, this is approved existing tags.
             } elseif (count($tagsToAdd) == 1) {
                 $this->_helper->flashMessenger(__('Your tag "%s" has been added', implode(', ', $tagsToAdd)), 'success');
             } else {
                 $this->_helper->flashMessenger(__('Your tags "%s" have been added', implode(', ', $tagsToAdd)), 'success');
             }
         }
     }
     $this->_helper->redirector->gotoUrl($destination);
 }