Skip to content

Commit

Permalink
extended finder tags method, finder facade and functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
thexmanxyz committed Nov 28, 2019
1 parent 8d98d5c commit fe44122
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 25 deletions.
104 changes: 90 additions & 14 deletions src/platforms/joomla/classes/Gantry/Joomla/Content/ContentFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ public function authorised($authorised = true)
$user = \JFactory::getUser();

// Define null and now dates
$nullDate = $this->db->quote($this->db->getNullDate());
$nowDate = $this->db->quote(\JFactory::getDate()->toSql());
$nullDate = $this->quote($this->db->getNullDate());
$nowDate = $this->quote(\JFactory::getDate()->toSql());

// Filter by start and end dates.
if (!$user->authorise('core.edit.state', 'com_content') && !$user->authorise('core.edit', 'com_content')) {
Expand All @@ -126,6 +126,94 @@ public function authorised($authorised = true)

return $this->where('a.access', 'IN', $groups)->where('c.access', 'IN', $groups);
}

public function tags($tags = [], $matchAll = false)
{
$tagTitles = !empty($tags['title'][0]) ? $tags['title'][0] : NULL;
$tagIds = !empty($tags['id'][0]) ? $tags['id'][0] : NULL;
$condition = '';
$result = $this;

if (is_null($tagTitles) && is_null($tagIds)) {
return $result;
}

// match all tag ids a/o titles
if ($matchAll){

//build up sub query and check for count
if(!is_null($tagTitles)) {
$condition .= "({$this->tagsCountSubQuery($tagTitles)}) >= " . count($tagTitles);
}

if (!is_null($tagIds)) {
if (strlen($condition) > 0){
$condition .= ' OR ';
}

$condition .= "({$this->tagsCountSubQuery($tagIds, true)}) >= " . count($tagIds);
}
$result = $this->query->where($condition);

// match any tag id a/o title
} else {

$this->query->join('INNER', '#__contentitem_tag_map AS tm ON tm.content_item_id = a.id');

// check if tag title exists for article
if (!is_null($tagTitles)) {
$this->query->join('INNER', '#__tags AS ta ON tm.tag_id = ta.id');
$condition .= "{$this->quoteName('ta.title')} IN {$this->toQuotedList($tagTitles)}";
}

// check if tag id exists for article
if (!is_null($tagIds)) {
if(strlen($condition) > 0){
$condition .= ' OR ';
}

array_map('intval', $tagIds);
$condition .= "{$this->quoteName('tm.tag_id')} IN {$this->toQuotedList($tagIds)}";
}

$this->query->where($condition);
$result = $this->where('tm.type_alias', '=', 'com_content.article');
}

return $result;
}

/**
* Creates a sub query to retrieve the tag id or tag title count.
*
* @param array $tags Tag ids or tag titles.
* @param boolean $ids Match ids or titles
*
* @return query
*/

protected function tagsCountSubQuery($tags = [], $ids = false)
{
// build up sub query for tag count
$subQuery = $this->db->getQuery(true)->select('COUNT(tm_s.tag_id)')->from($this->table . ' AS a_s');
$subQuery->join('INNER', '#__contentitem_tag_map AS tm_s ON tm_s.content_item_id = a_s.id');

if (!$ids) {
$subQuery->join('INNER', '#__tags AS ta_s ON tm_s.tag_id = ta_s.id');
}

// the referenced article has to match
$subQuery->where("{$this->quoteName('a_s.id')} = {$this->quoteName('a.id')}");

// check for tag ids or tag titles
if ($ids) {
$subQuery->where("{$this->quoteName('tm_s.tag_id')} IN {$this->toQuotedList($tags)}");
} else {
$subQuery->where("{$this->quoteName('ta_s.title')} IN {$this->toQuotedList($tags)}");
}

return $subQuery->where("{$this->quoteName('tm_s.type_alias')} = {$this->quote('com_content.article')}");
}

protected function addToGroup($key, $ids, $include = true)
{
Expand All @@ -148,16 +236,4 @@ protected function prepare()
}
}
}

public function tags($tagIds = [])
{
if (empty($tagIds['id'][0])) {
return $this;
}

$tagIdsArray = array_map('intval', $tagIds['id'][0]);
$this->query->join('INNER', '#__contentitem_tag_map AS t ON t.content_item_id = a.id');

return $this->where('t.tag_id', 'IN', $tagIdsArray)->where('t.type_alias', '=', 'com_content.article');
}
}
53 changes: 42 additions & 11 deletions src/platforms/joomla/classes/Gantry/Joomla/Object/Finder.php
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public function order($by, $direction = 1, $alias = 'a')
} else {
$direction = strtolower((string)$direction) == 'desc' ? 'DESC' : 'ASC';
}
$by = (string)$alias . '.' . $this->db->quoteName($by);
$by = (string)$alias . '.' . $this->quoteName($by);
$this->query->order("{$by} {$direction}");

return $this;
Expand All @@ -141,7 +141,6 @@ public function order($by, $direction = 1, $alias = 'a')
*/
public function where($field, $operation, $value)
{
$db = $this->db;
$operation = strtoupper($operation);
switch ($operation)
{
Expand All @@ -151,16 +150,16 @@ public function where($field, $operation, $value)
case '<=':
case '=':
// Quote all non integer values.
$value = (string)(int)$value === (string)$value ? (int)$value : $db->quote($value);
$this->query->where("{$this->db->quoteName($field)} {$operation} {$value}");
$value = (string)(int)$value === (string)$value ? (int)$value : $this->quote($value);
$this->query->where("{$this->quoteName($field)} {$operation} {$value}");
break;
case 'BETWEEN':
case 'NOT BETWEEN':
list($a, $b) = (array) $value;
// Quote all non integer values.
$a = (string)(int)$a === (string)$a ? (int)$a : $db->quote($a);
$b = (string)(int)$b === (string)$b ? (int)$b : $db->quote($b);
$this->query->where("{$this->db->quoteName($field)} {$operation} {$a} AND {$b}");
$a = (string)(int)$a === (string)$a ? (int)$a : $this->quote($a);
$b = (string)(int)$b === (string)$b ? (int)$b : $this->quote($b);
$this->query->where("{$this->quoteName($field)} {$operation} {$a} AND {$b}");
break;
case 'IN':
case 'NOT IN':
Expand All @@ -169,10 +168,7 @@ public function where($field, $operation, $value)
// WHERE field IN (nothing).
$this->query->where('0');
} else {
// Quote all non integer values.
array_walk($value, function (&$value) use ($db) { $value = (string)(int)$value === (string)$value ? (int)$value : $db->quote($value); });
$list = implode(',', $value);
$this->query->where("{$this->db->quoteName($field)} {$operation} ({$list})");
$this->query->where("{$this->quoteName($field)} {$operation} {$this->toQuotedList($value)}");
}
break;
}
Expand Down Expand Up @@ -224,6 +220,41 @@ public function count()

return $count;
}

/**
* Quote value.
*
* @return string
*/
protected function quote($value)
{
return $this->db->quote($value);
}

/**
* Quote name.
*
* @return string
*/
protected function quoteName($value)
{
return $this->db->quoteName($value);
}

/**
* Quote all non integer values and return as string in the form
* (int1, int2, int3) or ('string1', 'string2', 'string3').
*
* @param string|array $value Value.
*
* @return string
*/
protected function toQuotedList($value)
{
array_walk($value, function (&$value) { $value = (string)(int)$value === (string)$value ? (int)$value : $this->quote($value); });
return '(' . implode(',', $value) . ')';
}


/**
* Override to include common where rules.
Expand Down

0 comments on commit fe44122

Please sign in to comment.