├── .gitignore ├── TagEngine.class.php ├── index.php ├── readme.md └── tables.sql /.gitignore: -------------------------------------------------------------------------------- 1 | #Mac OS X files 2 | .DS_Store 3 | 4 | #Vim trash 5 | *.swp -------------------------------------------------------------------------------- /TagEngine.class.php: -------------------------------------------------------------------------------- 1 | 8 | * @copyright Copyright (c) 2010, Josh Campbell 9 | * @license http://opensource.org/licenses/gpl-3.0.html GNU Public License 10 | * @version 1.0 11 | **/ 12 | class TagEngine 13 | { 14 | /** 15 | * MySqliDb instance 16 | * 17 | * @var mixed 18 | */ 19 | protected $db; 20 | /** 21 | * Name of the tags table in the database 22 | * 23 | * @var string 24 | */ 25 | protected $tableTags = 'sysTags'; 26 | /** 27 | * Name of the tagmap types table in the database 28 | * 29 | * @var string 30 | */ 31 | protected $tableTagTypes = 'sysTagTypes'; 32 | /** 33 | * Name of the tagmaps table in the database 34 | * 35 | * @var string 36 | */ 37 | protected $tableTagMaps = 'sysTagMaps'; 38 | /** 39 | * The minimum number of characters a tag can have. 40 | * 41 | * @var integer 42 | */ 43 | protected $_tagLen = 2; 44 | 45 | /** 46 | * Initialize TagEngine - Load database instance 47 | */ 48 | public function __construct() 49 | { 50 | $this->db = MySqliDb::getInstance(); 51 | } 52 | 53 | /** 54 | * Set/Change the TagEngine tables. 55 | * 56 | * @uses tagEngine->setTables('myAppTags', 'myAppTagTypes', 'myAppTagMaps') 57 | * 58 | * @param string $tableTags The name of the tags table. 59 | * @param string $tableTagTypes The name of the tag types table. 60 | * @param string $tableTagMaps The name of the tag maps table. 61 | */ 62 | public function setTables($tableTags, $tableTagTypes, $tableTagMaps) 63 | { 64 | $this->tableTags = $tableTags; 65 | $this->tableTagTypes = $tableTagTypes; 66 | $this->tableTagMaps = $tableTagMaps; 67 | } 68 | 69 | /** 70 | * Set/Change the minimum tag length. 71 | * 72 | * @uses tagEngine->setTagLen(2) 73 | * 74 | * @param integer $tagLen The minimum number of characters a tag can have. 75 | */ 76 | public function setTagLen($tagLen) 77 | { 78 | $this->_tagLen = $tagLen; 79 | } 80 | 81 | /** 82 | * Get the id of a tag name. 83 | * 84 | * @uses TagEngine->getTagId('tagName') 85 | * 86 | * @param string $name The tag name. 87 | * @return mixed Returns the tagId if the tag exists, false if it does not. 88 | */ 89 | public function getTagId($name) 90 | { 91 | $this->db->where('name',trim($name)); 92 | $result = $this->db->query("SELECT tagId FROM $this->tableTags",1); 93 | 94 | if (!empty($result)) { 95 | $tagId = $result[0]['tagId']; 96 | return $tagId; 97 | } else { 98 | return false; 99 | } 100 | } 101 | 102 | /** 103 | * Does the tag name exist? 104 | * 105 | * @uses TagEngine->tagExists('tagName') 106 | * 107 | * @param string $name The tag name. 108 | * @return boolean Returns true if the tag exists, false if it does not. 109 | */ 110 | public function tagExists($name) 111 | { 112 | ($this->getTagId($name)) ? $result = true : $result = false; 113 | return $result; 114 | } 115 | 116 | /** 117 | * Get the tag type's id. 118 | * 119 | * @uses TagEngine->getTagTypeId('type') 120 | * 121 | * @param string $type The 3 character tag type name. (Not to be confused with the longName.) 122 | * @return mixed Returns the typeId if the tag type exists, false if it does not. 123 | */ 124 | public function getTagTypeId($type) 125 | { 126 | $this->db->where('name',trim($type)); 127 | $result = $this->db->query("SELECT typeId FROM $this->tableTagTypes",1); 128 | 129 | if (!empty($result)) { 130 | $tagId = $result[0]['typeId']; 131 | return $tagId; 132 | } else { 133 | trigger_error('Invalid tag type: "'.$type.'"', E_USER_ERROR); 134 | } 135 | } 136 | 137 | /** 138 | * Get the tagId/tags for an entity of the given relative id and type. 139 | * 140 | * @uses TagEngine->getTags(relId, type) 141 | * 142 | * @param integer $relId The id of the entity being searched. 143 | * @param string $type The 3 character tag type name being searched. (Not to be confused with the longName.) 144 | * @return array Returns an array of string containing the tags where the key is the tagId and the data is the tag name. 145 | */ 146 | public function getTags($relId, $type) 147 | { 148 | $tagsArr = array(); // Temporary tags array. 149 | 150 | $typeId = $this->getTagTypeId($type); 151 | 152 | $this->db->where('typeId', $typeId); 153 | $this->db->where('relId', $relId); 154 | $result = $this->db->query("SELECT tagId FROM $this->tableTagMaps"); 155 | foreach($result as $row) { 156 | $tagsArr[$row['tagId']] = htmlentities(stripslashes($this->getTagName($row['tagId']))); 157 | //array_push($tagsArr,$this->getTagName($row['tagId'])); 158 | } 159 | return $tagsArr; 160 | } 161 | 162 | /** 163 | * Get all tagId/tags. 164 | * 165 | * @uses TagEngine->getAllTags() 166 | * 167 | * @return array Returns an array of strings containing the tags where the key is the tagId and the data is the tag name. 168 | */ 169 | public function getAllTags() 170 | { 171 | $tagsArr = array(); // Temporary tags array. 172 | 173 | $result = $this->db->get($this->tableTagMaps); 174 | foreach($result as $row) { 175 | $tagsArr[$row['tagId']] = $this->getTagName($row['tagId']); 176 | //array_push($tagsArr,$this->getTagName($row['tagId'])); 177 | } 178 | return $tagsArr; 179 | } 180 | 181 | /** 182 | * Get the tag name. 183 | * 184 | * @uses TagEngine->getTagName(tagId) 185 | * 186 | * @param integer $tagId The id of the tag to be retrived. 187 | * @return string Returns the tag name of the given tagId. 188 | */ 189 | public function getTagName($tagId) 190 | { 191 | $this->db->where('tagId', $tagId); 192 | $result = $this->db->query("SELECT name FROM $this->tableTags",1); 193 | return $result[0]['name']; 194 | } 195 | 196 | /** 197 | * Adds tags to the database if they do not already exist and creates tag maps to them. 198 | * 199 | * @uses TagEngine->mapTags(105, 'img', 'tag1,tag2,tag3') 200 | * 201 | * @param integer $relId The id of the entity being tagged. 202 | * @param string $type The 3 character type. 203 | * @param string $tags A comma delimited string of tags to be mapped to the relId. 204 | * @return array Returns an array containing 2 other arrays, [tagIDs] and [mapIds] each contains the id's to their respective referances for each tag/map created. 205 | */ 206 | public function mapTags($relId, $type, $tags) 207 | { 208 | $tagIds = array(); 209 | $mapIds = array(); 210 | 211 | $tagsArr = explode(',', $tags); 212 | 213 | $typeId = $this->getTagTypeId($type); 214 | 215 | $i = 0; 216 | foreach ($tagsArr as $tag) { 217 | $tag = trim($tag); 218 | if (strlen($tag) >= $this->_tagLen) { // Tag must be at least X characters. 219 | $tagId = $this->getTagId($tag); // If the tag exists get its ID. 220 | if (!$tagId) $tagId = $this->insertTag($tag); // If not, create the tag and get the new id. 221 | array_push($tagIds, $tagId); 222 | 223 | $result = $this->addTagMap($relId, $typeId, $tagId); // Add tag map for this tag if it does not already exist. 224 | array_push($mapIds, $result); 225 | } 226 | $i++; 227 | } 228 | $results = array('tagIds' => $tagIds, 'mapIds' => $mapIds); // Build the id arrays 229 | return $results; 230 | } 231 | 232 | /** 233 | * Insert a tag 234 | * 235 | * @uses TagEngine->insertTag('tagname') 236 | * 237 | * @param string $name The tag to be inserted. 238 | * @return integer Returns the id of the tag that was inserted. 239 | */ 240 | protected function insertTag($name) 241 | { 242 | $insertData = array('name' => $name); 243 | return $this->db->insert($this->tableTags, $insertData); 244 | } 245 | 246 | /** 247 | * Creates a map entry between a relative id, tag, and type if one does not already exist. 248 | * 249 | * @uses TagEngine->addTagMap(relId,typeId,tagId) 250 | * 251 | * @param integer $relId The id of the entity being tagged. 252 | * @param integer $typeId The id of the type of tag being mapped. 253 | * @param integer $tagId The id of the tag being mapped to. 254 | * @return integer Returns the id of the map that was inserted or false if it exists or there was an error inserting. 255 | */ 256 | protected function addTagMap($relId, $typeId, $tagId) 257 | { 258 | $this->db->where('relId', $relId); 259 | $this->db->where('typeId', $typeId); 260 | $this->db->where('tagId', $tagId); 261 | $result = $this->db->query("SELECT id FROM $this->tableTagMaps",1); // Check for existing map. 262 | if (empty($result)) { 263 | $insertData = array( 264 | 'relId' => $relId, 265 | 'typeId' => $typeId, 266 | 'tagId' => $tagId); 267 | $result = $this->db->insert($this->tableTagMaps, $insertData); // Add new map. 268 | } else { 269 | $result = $result[0]['id']; // Get the id of existing the map. 270 | } 271 | return $result; 272 | } 273 | 274 | /** 275 | * When deleting an entity, use this method to remove its tag maps and delete the tags mapped to it if they are no longer in use. 276 | * 277 | * @uses TagEngine->cleanTags(relId,type) 278 | * 279 | * @param integer $relId The id of the entity being cleaned. 280 | * @param integer $typeId The type of tag being cleaned. 281 | */ 282 | public function cleanTags($relId, $type) 283 | { 284 | $tagsArr = $this->getTags($relId, $type); 285 | foreach($tagsArr as $tag) { // Loop through each tag mapped to this entity and remove the mapping. 286 | $tagId = $this->getTagId($tag); 287 | $this->removeTagMap($relId, $type, $tagId); 288 | } 289 | } 290 | 291 | /** 292 | * Remove a tag map and delete the tag it was mapped to if that tag is no longer mapped to any other entity of any type. 293 | * 294 | * @uses TagEngine->removeTagMap(relId,typeId,tagId) 295 | * 296 | * @param integer $relId The id of the entity map being removed. 297 | * @param integer $type The 3 character string representing the the type of tag being removed. 298 | * @param integer $tagId The id of the tag being unmapped. 299 | */ 300 | public function removeTagMap($relId, $type, $tagId) 301 | { 302 | $typeId = $this->getTagTypeId($type); 303 | 304 | $this->db->where('relId', $relId); 305 | $this->db->where('typeId', $typeId); 306 | $this->db->where('tagId', $tagId); 307 | $this->db->delete($this->tableTagMaps, 1); // Remove the tag map. 308 | 309 | $this->db->where('tagId', $tagId); 310 | $results = $this->db->query("SELECT id FROM $this->tableTagMaps"); 311 | if (empty($results)) { // If the tag is no longer in use, delete it as well. 312 | $this->removeTag($tagId); 313 | } 314 | } 315 | 316 | /** 317 | * Removes a tag. 318 | * 319 | * @uses TagEngine->removeTag(tagId) 320 | * 321 | * @param integer $tagId The id of the tag being removed. 322 | */ 323 | protected function removeTag($tagId) 324 | { 325 | $this->db->where('tagId', $tagId); 326 | $this->db->delete($this->tableTags, 1); 327 | } 328 | 329 | } // END class -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | PHP TagEngine 14 | 15 | 16 | 17 | 18 |

Use tabels.sql to create the tag engine tabels and insert test data (tag types).

19 | 20 | Tag Engine Tests

'; 24 | 25 | echo 'getTagTypeId(\'img\') = '.$tagEngine->getTagTypeId('img').'

'; 26 | 27 | echo '
Insert 3 new tags (tag1,tag2,tag3) and map them to relId 100 with a type of img.'."\nmapTags(100,'img','tag1,tag2,tag3') =\n";
28 | print_r ($tagEngine->mapTags(100, 'img', 'tag1,tag2,tag3'));
29 | echo '

'; 30 | 31 | echo 'getTagId(\'tag3\') = '.$tagEngine->getTagId('tag3').'
'; 32 | echo 'tagExists(\'tag3\') = '; 33 | if ($tagEngine->tagExists('tag3')) 34 | { 35 | echo 'true
'; 36 | }else{ 37 | echo 'false
'; 38 | } 39 | 40 | echo 'tagExists(\'tag5\') = '; 41 | if ($tagEngine->tagExists('tag5')) 42 | { 43 | echo 'true
'; 44 | }else{ 45 | echo 'false
'; 46 | } 47 | 48 | echo '
Get all tagMaps with a relId of 100 and a type of img.'."\ngetTags(100,'img') =\n";
49 | print_r ($tagEngine->getTags(100, 'img'));
50 | echo '
'; 51 | 52 | echo '
Remove all tagmaps with a relId of 100 and a type of img, and delete the tags if they are not used by any other entity.
'."cleanTags(100,'img')
"; 53 | $tagEngine->cleanTags(100, 'img'); 54 | 55 | echo '
Get all tagMaps with a relId of 100 and a type of img.'."\ngetTags(100,'img') =\n";
56 | print_r ($tagEngine->getTags(100, 'img'));
57 | echo '
'; 58 | 59 | ?> 60 | 61 | 62 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | TagEngine simplifies and automates the handeling of tags and tag maps in a system that requires one or more types of entities to be tagged.

2 | Use tabels.sql to create the tag engine tabels and insert test data (tag types).

3 | To utilize this class, first import TagEngine.php into your project, and require it.
4 | This class also utilizes a MySQLi wrapper that can be found here: http://github.com/ajillion/PHP-MySQLi-Database-Class
5 | It can easily be modified to support the ORM of your choice, or none at all if you enjoy using the crappy mysql_connect procedural method of database access. 6 | 7 |
  8 | 
  9 | require_once('Mysqlidb.php');
 10 | require_once('TagEngine.php');
 11 | 
 12 | 
13 | 14 | After that, create a new instance of the MySQLi wrapper and the TagEngine.
15 | Be sure to pass the newly created database object to the TagEnigne when you instantiate it. 16 | 17 |
 18 | 
 19 | $db = new Mysqlidb('host', 'username', 'password', 'databaseName');
 20 | $tagEngine = new TagEngine($db);
 21 | 
 22 | 
23 | 24 |

Setup Methods

25 | 26 |

Allows changing of the default TagEngine settings.

27 |
 28 | 
 29 | setTables('myTagsTable', 'myTagTypesTable', 'myTagMapsTable');   // Set up the tag engine tabels
 31 | $tagEngine->setTagLen(4);   // Set the minimum number of characters a tag must have.
 32 | 
 33 | 
34 | 35 |

mapTags Method

36 | 37 |

Creates tag maps to existing tags, and adds tags that do not exist yet.

38 |
 39 | 
 40 | $tagEngine->mapTags(100, 'img', 'tag1,tag2,tag3');		// Create's 3 new tags and maps them to the relative id 
 41 |                                                       //  of 100 with a type of img (Image).
 42 | 
 43 | 
44 | 45 |

getTagId Method

46 | 47 |

Retrives the tag id for the given tag name.

48 |
 49 | 
 50 | $tagEngine->getTagId('tag3');   // Retreive the tag id for 'tag3'.
 51 | 
 52 | 
53 | 54 | 55 |

getTagName Method

56 | 57 |

Retrives the tag name of the given tag id

58 |
 59 | 
 60 | $tagEngine->getTagName(1);   //  Gets the tag name for tag id 1
 61 | 
 62 | 
63 | 64 |

tagExists Method

65 | 66 |

Checks to see if the given tag exists.

67 |
 68 | 
 69 | if ($tagEngine->tagExists('tag5'))   // If the tag exists the method returns true, if it does not it returns false.
 70 | {
 71 | 	echo 'true';
 72 | }else{
 73 | 	echo 'false';
 74 | }
 75 | 
 76 | 
77 | 78 |

getTagTypeId Method

79 | 80 |

Retrives the id of the given type.

81 |
 82 | 
 83 | $tagEngine->getTagTypeId('img');   // Gets the id for type 'img' (Image)
 84 | 
 85 | 
86 | 87 |

getTags Method

88 | 89 |

Retrives tags mapped to an entity of a particular type and returns them in a zero indexed array.

90 |
 91 | 
 92 | $tagEngine->getTags(100, 'img');   // Gets all tags that are mapped to relative id 100 and type img (Image).
 93 | 
 94 | 
95 | 96 |

cleanTags Method

97 | 98 |

Removes all tag maps for the given relative id and type. Also removes the tag if it is no longer mapped to any other entity.

99 |
100 | 
101 | $tagEngine->cleanTags(100, 'img');   // Removes all tag maps to relative id 100 of type 'img' (Image) and deletes the tags
102 |                                      // that weremapped to it (tag1,tag2,tag3) since they are no longer in use.
103 | 
104 | 
105 | 106 |

removeTagMap Method

107 | 108 |

Manualy remove one tag map with the given parameters.

109 |
110 | 
111 | $tagEngine->removeTagMap(100, 'img', 1); // Remove the tag map to relative id 100 of type 'img' (Image) where the tag id is 1
112 | 
113 | 
114 | -------------------------------------------------------------------------------- /tables.sql: -------------------------------------------------------------------------------- 1 | # 2 | # Encoding: Unicode (UTF-8) 3 | # 4 | 5 | 6 | CREATE TABLE `sysTagMaps` ( 7 | `id` int(11) NOT NULL AUTO_INCREMENT, 8 | `relId` int(11) NOT NULL DEFAULT '0', 9 | `typeId` int(11) NOT NULL DEFAULT '0', 10 | `tagId` int(11) NOT NULL DEFAULT '0', 11 | PRIMARY KEY (`id`), 12 | KEY `relId` (`relId`), 13 | KEY `tagId` (`tagId`), 14 | KEY `typeId` (`typeId`) 15 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 16 | 17 | 18 | CREATE TABLE `sysTags` ( 19 | `tagId` int(11) NOT NULL AUTO_INCREMENT, 20 | `name` varchar(50) NOT NULL DEFAULT '', 21 | PRIMARY KEY (`tagId`) 22 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 23 | 24 | 25 | CREATE TABLE `sysTagTypes` ( 26 | `typeId` int(11) NOT NULL AUTO_INCREMENT, 27 | `name` varchar(3) NOT NULL DEFAULT '', 28 | `longName` varchar(50) NOT NULL DEFAULT '', 29 | PRIMARY KEY (`typeId`) 30 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 31 | 32 | 33 | SET FOREIGN_KEY_CHECKS = 0; 34 | 35 | 36 | LOCK TABLES `sysTagTypes` WRITE; 37 | INSERT INTO `sysTagTypes` (`typeId`, `name`, `longName`) VALUES (1, 'pst', 'Post'); 38 | INSERT INTO `sysTagTypes` (`typeId`, `name`, `longName`) VALUES (2, 'img', 'Image'); 39 | INSERT INTO `sysTagTypes` (`typeId`, `name`, `longName`) VALUES (3, 'doc', 'Document'); 40 | UNLOCK TABLES; 41 | 42 | 43 | SET FOREIGN_KEY_CHECKS = 1; 44 | --------------------------------------------------------------------------------