As the title says: How do I programatically add one or more tags to an existing product? I couldn't find anything useful about this topic on the internet, so every help, link or knowledge is welcome.
Thanks in advance!
Ok I found it by myself. I've copied and customized the saveAction() of the app/code/core/Mage/Tag/Controllers/IndexController.php and also some additional functions to get this thing to work.
require_once $_SERVER['DOCUMENT_ROOT'] . "/app/Mage.php";
umask(0);
Mage::app();
Mage::app()->getTranslator()->init('frontend');
Mage::getSingleton('core/session', array('name' => 'frontend'));
$customerSession = Mage::getSingleton('customer/session');
$tagName = 'Urban Extraloud';//(string) $this->getRequest()->getQuery('productTagName');
$productId = 257;//(int)$this->getRequest()->getParam('product');
if(strlen($tagName) && $productId) {
$session = Mage::getSingleton('catalog/session');
$product = Mage::getModel('catalog/product')
->load($productId);
if(!$product->getId()){
//$session->addError($this->__('Unable to save tag(s).'));
} else {
try {
$customerId = 58; //$customerSession->getCustomerId();
$storeId = Mage::app()->getStore()->getId();
$tagNamesArr = _cleanTags(_extractTags($tagName));
$counter = new Varien_Object(array(
"new" => 0,
"exist" => array(),
"success" => array(),
"recurrence" => array())
);
$tagModel = Mage::getModel('tag/tag');
$tagRelationModel = Mage::getModel('tag/tag_relation');
foreach ($tagNamesArr as $tagName) {
$tagModel->unsetData()
->loadByName($tagName)
->setStoreId($storeId)
->setName($tagName);
$tagRelationModel->unsetData()
->setStoreId($storeId)
->setProductId($productId)
->setCustomerId($customerId)
->setActive(Mage_Tag_Model_Tag_Relation::STATUS_ACTIVE)
->setCreatedAt( $tagRelationModel->getResource()->formatDate(time()) );
if (!$tagModel->getId()) {
$tagModel->setFirstCustomerId($customerId)
->setFirstStoreId($storeId)
->setStatus($tagModel->getPendingStatus())
->save();
$tagRelationModel->setTagId($tagModel->getId())->save();
$counter->setNew($counter->getNew() + 1);
} else {
$tagStatus = $tagModel->getStatus();
$tagRelationModel->setTagId($tagModel->getId());
switch($tagStatus) {
case $tagModel->getApprovedStatus():
if(_checkLinkBetweenTagProduct($tagRelationModel)) {
$relation = _getLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel);
if ($relation->getId()) {
if (!$relation->getActive()) {
$tagRelationModel
->setId($relation->getId())
->save();
}
} else {
$tagRelationModel->save();
}
$counter->setExist(array_merge($counter->getExist(), array($tagName)));
} else {
$tagRelationModel->save();
$counter->setSuccess(array_merge($counter->getSuccess(), array($tagName)));
}
break;
case $tagModel->getPendingStatus():
$relation = _getLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel);
if ($relation->getId()) {
if (!$relation->getActive()) {
$tagRelationModel
->setId($relation->getId())
->save();
}
} else {
$tagRelationModel->save();
}
$counter->setNew($counter->getNew() + 1);
break;
case $tagModel->getDisabledStatus():
if(_checkLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel)) {
$counter->setRecurrence(array_merge($counter->getRecurrence(), array($tagName)));
} else {
$tagModel->setStatus($tagModel->getPendingStatus())->save();
$tagRelationModel->save();
$counter->setNew($counter->getNew() + 1);
}
break;
}
}
}
} catch (Exception $e) {
print 'Unable to save tag(s)';
}
}
}
function _extractTags($tagNamesInString)
{
return explode("\n", preg_replace("/(\'(.*?)\')|(\s+)/i", "$1\n", $tagNamesInString));
}
/**
* Clears the tag from the separating characters.
*
* @param array $tagNamesArr
* @return array
*/
function _cleanTags(array $tagNamesArr)
{
foreach( $tagNamesArr as $key => $tagName ) {
$tagNamesArr[$key] = trim($tagNamesArr[$key], '\'');
$tagNamesArr[$key] = trim($tagNamesArr[$key]);
if( $tagNamesArr[$key] == '' ) {
unset($tagNamesArr[$key]);
}
}
return $tagNamesArr;
}
/**
* Checks whether the already marked this product in this store by this tag.
*
* @param Mage_Tag_Model_Tag_Relation $tagRelationModel
* @return boolean
*/
function _checkLinkBetweenTagProduct($tagRelationModel)
{
$customerId = $tagRelationModel->getCustomerId();
$tagRelationModel->setCustomerId(null);
$res = in_array($tagRelationModel->getProductId(), $tagRelationModel->getProductIds());
$tagRelationModel->setCustomerId($customerId);
return $res;
}
/**
* Checks whether the already marked this product in this store by this tag and by this customer.
*
* @param Mage_Tag_Model_Tag_Relation $tagRelationModel
* @param Mage_Tag_Model_Tag $tagModel
* @return boolean
*/
function _checkLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel)
{
return (count(_getLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel)
->getProductIds()) > 0);
}
/**
* Get relation model for marked product in this store by this tag and by this customer.
*
* @param Mage_Tag_Model_Tag_Relation $tagRelationModel
* @param Mage_Tag_Model_Tag $tagModel
* @return Mage_Tag_Model_Tag_Relation
*/
function _getLinkBetweenTagCustomerProduct($tagRelationModel, $tagModel)
{
return Mage::getModel('tag/tag_relation')->loadByTagCustomer(
$tagRelationModel->getProductId(),
$tagModel->getId(),
$tagRelationModel->getCustomerId(),
$tagRelationModel->getStoreId()
);
}