* @license PHP License * @package WB * @subpackage Tag */ WBClass::load('WBDatasource_XReference'); /** * Tag Stuff * * Find and list tags * * @version 0.4.3 * @package WB * @subpackage db */ class WBDatasource_Tag extends WBStdClass { /** * Table access * @var WBDatasource_Table */ private $table; /** * Primary key of tags * @var string */ private $pTag; /** * Primary key of mandator * @var string */ private $pMan; /** * Locale cache */ static $cache = array(); const TABLE_APP = 'tagappearance'; /** * Prepare Clause * @var array */ private $clause = array( array( 'field' => 'enabled', 'value' => '1', 'table' => WBDatasource::TABLE_TAG ), /* array( 'field' => 'namespace', 'relation' => 'eq', 'value' => '', 'table' => WBDatasource::TABLE_TAGREF ), array( 'field' => 'xid', 'relation' => 'eq', 'value' => '', 'table' => WBDatasource::TABLE_TAGREF ), */ ); /** * Prepare Clause 4 Namespace * @var array */ private $clauseNamespace = array(); /** * Prepare Clause 4 XID * @var array */ private $clauseXId = array(); /** * Initialize * * @param array $parameter */ public function __construct($parameter = array()) { $this->table = WBClass::create('WBDatasource_Table'); $this->pTag = $this->table->getIdentifier(WBDatasource::TABLE_TAG); $this->pMan = $this->table->getIdentifier(WBDatasource::TABLE_MANDATOR); } /** * Set Namespace * * @param string|array */ public function setNamespace($ns) { if (empty($this->clauseNamespace)) { $this->clauseNamespace[0] = array( 'field' => 'namespace', 'relation' => 'eq', 'value' => '', 'table' => WBDatasource::TABLE_TAGREF ); } if (is_array($ns)) { $this->clauseNamespace[0]['relation']= 'in'; $this->clauseNamespace[0]['value'] = $ns; return; } $this->clauseNamespace[0]['relation']= 'eq'; $this->clauseNamespace[0]['value'] = trim($ns); } /** * Set X-ID * * @param string|array */ public function setXId($xid) { $this->clauseXId = array(); if (!is_array($xid)) { $xid = array($xid); } $xids = array(); foreach ($xid as $x) { if (strstr($x, '-')) { $id = explode('-', $x); if (!isset($this->clauseXId[0])) { $this->clauseXId[0] = array( 'field' => $this->table->getIdentifier(WBDatasource::TABLE_MANDATOR, true), 'value' => $id[0], 'table' => WBDatasource::TABLE_TAGREF ); } $x = array_pop($id); } $xids[] = $x; } $this->clauseXId[] = array( 'field' => 'xid', 'relation' => 'in', 'value' => $xids, 'table' => WBDatasource::TABLE_TAGREF ); } /** * Fetch List of Tags * * Get all tags for namespace and xid with usage count of each tag * * @return array $list */ public function get() { $clause = $this->clause; if (!empty($this->clauseNamespace)) { $clause = array_merge($clause, $this->clauseNamespace); } if (!empty($this->clauseXId)) { $clause = array_merge($clause, $this->clauseXId); } $cId = md5(serialize($clause)); if (isset(self::$cache[$cId])) { return self::$cache[$cId]; } self::$cache[$cId] = $this->getTagsByClause($clause); return self::$cache[$cId]; } /** * Select Tags Using Clause * * @param array */ private function getTagsByClause($clause) { $opt = array(); $opt['groupby'] = array(); $opt['groupby'][] = array( 'field' => $this->pTag ); $opt['join'] = array(); $opt['join'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'using' => $this->pTag ); $opt['column'] = array('*'); $opt['column'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => 'namespace' ); $tags = $this->table->get(WBDatasource::TABLE_TAG, null, null, $clause, $opt); $this->injectTagCount($tags); return $tags; } /** * Get Tag References * * Select references for all namespaces * * @param array $tagIds */ public function getX($tagIds) { if (empty($tagIds)) { return array(); } // sort for caching sort($tagIds); $clause = $this->clause; if (!empty($this->clauseNamespace)) { $clause = array_merge($clause, $this->clauseNamespace); } $cnt = count($tagIds); $clause[] = array( 'field' => $this->pTag, 'relation' => 'in', 'value' => $tagIds ); $opt = array(); $opt['order'] = array(); $opt['order'][] = array( 'table' => WBDatasource::TABLE_TAG, 'field' => $this->pTag ); $opt['order'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => 'namespace' ); // $opt['column'] = array('*'); $opt['column'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => '*', ); $opt['groupby'] = array(); $opt['groupby'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => $this->pMan ); $opt['groupby'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => 'namespace' ); $opt['groupby'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'field' => 'xid', 'having' => sprintf('%d = count(*)', $cnt) ); $opt['join'] = array(); $opt['join'][] = array( 'table' => WBDatasource::TABLE_TAGREF, 'using' => $this->pTag ); $tags = $this->table->get(WBDatasource::TABLE_TAG, null, null, $clause, $opt); return $tags; } /** * Count Usage for Each Tag * * * * @param array $tags */ private function injectTagCount(&$tags) { if (empty($tags)) { return; } $tIds = array(); foreach ($tags as $t) { $tIds[] = $t['id']; } // select count $clause = array(); $clause[] = array( 'field' => $this->pTag, 'relation' => 'in', 'value' => $tIds ); $opt = array(); $opt['groupby'] = array(); $opt['groupby'][] = array( 'field' => $this->pTag ); $opt['column'] = array(); $opt['column'][] = array( 'field' => $this->pTag, 'as' => 'id' ); $opt['column'][] = array( 'field' => $this->pTag, 'function' => 'count', 'as' => 'count' ); $count = $this->table->get(WBDatasource::TABLE_TAGREF, null, null, $clause, $opt); // inject count to existing tag list foreach ($tags as &$t) { foreach ($count as $c) { if ($t['id'] == $c['id']) { $t['count'] = $c['count']; continue 2; } } } } /** * Find Tags * * Search for matching tags in language and return list * * @todo Language / translation support not implemented, yet * * @param array * @param $lang * @return array */ public function find($tags, $lang = 'C', $idsOnly = false) { if (empty($tags)) { return array(); } // get all tags and check if translations matches $clause = array(); $clause[] = array( 'field' => 'enabled', 'value' => 1 ); $col = 'tag'; if ('C' != $lang) { $col .= '_' . strtolower($lang); } $c = array(); foreach ($tags as $t) { if (2 > strlen($t)) { continue; } $c[] = array( 'field' => $col, // 'relation' => 'like', 'value' => $t ); } if (empty($c)) { return array(); } $clause[] = array( 'type' => 'complex', 'bond' => 'or', 'clause' => $c ); if ($idsOnly) { return $this->table->getIds(WBDatasource::TABLE_TAG, null, $clause); } $list = $this->table->get(WBDatasource::TABLE_TAG, null, null, $clause); $this->injectTagCount($list); return $list; } /** * Get Tag Data By Id * * @param string $id * @return array */ public function getById($id) { $list = $this->table->get(WBDatasource::TABLE_TAG, $id); if (1 != count($list)) { return array(); } $this->injectTagCount($list); $list = $list[0]; return $list; } public function getAppearance($tagId, $ns = null, $xid = null) { $clause = array(); $clause[] = array( 'field' => $this->pTag, 'value' => $tagId ); if ($ns) { $clause[] = array( 'field' => 'namespace', 'value' => $ns ); } if ($xid) { $clause[] = array( 'field' => 'xid', 'value' => $xid ); } $opt = array(); $opt['column'] = array(); $opt['column'][]= array( 'field' => $this->pTag, 'as' => 'id' ); $opt['column'][]= array( 'field' => $this->pTag, 'function' => 'count', 'as' => 'count' ); $opt['column'][]= array( 'field' => 'tagcount', 'function' => 'sum', 'as' => 'appearance' ); $list = $this->table->get(self::TABLE_APP, null, null, $clause, $opt); $list = $list[0]; if (empty($list['id'])) { $list['id'] = $tagId; $list['count'] = 0; $list['appearance'] = 0; } return $list; } }