<?php
namespace Your\Namespace\Criteria;
use XF\Criteria\AbstractCriteria;
class Thread extends AbstractCriteria
{
/**
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
public function isMatchedThread(\XF\Entity\Thread $thread)
{
if (!$this->criteria)
{
return $this->matchOnEmpty;
}
foreach ($this->criteria AS $criterion)
{
$rule = $criterion['rule'];
$data = $criterion['data'];
$specialResult = $this->isSpecialMatchedThread($rule, $data, $thread);
if ($specialResult === false)
{
return false;
}
else if ($specialResult === true)
{
continue;
}
$method = '_matchThread' . \XF\Util\Php::camelCase($rule);
if (method_exists($this, $method))
{
$result = $this->$method($data, $thread);
if (!$result)
{
return false;
}
}
else
{
if (!$this->isUnknownMatchedThread($rule, $data, $thread))
{
return false;
}
}
}
return true;
}
/**
* @param $rule
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool|null
*/
protected function isSpecialMatchedThread($rule, array $data, \XF\Entity\Thread $thread)
{
// custom user fields
if (preg_match('/^thread_field_(.+)$/', $rule, $matches))
{
/** @var \XF\CustomField\Set|null $cFS */
$cFS = $thread->thread_id ? $thread->custom_fields : null;
$fieldId = $matches[1];
if (!$cFS || !isset($cFS->{$fieldId}))
{
return false;
}
$value = $cFS->{$fieldId};
// text fields - check that data exists within the text value
if (isset($data['text']))
{
if (stripos($value, $data['text']) === false)
{
return false;
}
}
// choice fields - check that data is in the choice array
else if (isset($data['choices']))
{
// multi-choice
if (is_array($value))
{
if (!array_intersect($value, $data['choices']))
{
return false;
}
}
// single choice
else
{
if (!in_array($value, $data['choices']))
{
return false;
}
}
}
return true;
}
return null;
}
/**
* @param $rule
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function isUnknownMatchedThread($rule, array $data, \XF\Entity\Thread $thread)
{
$eventReturnValue = false;
$this->app->fire('your_namespace_criteria_thread', [$rule, $data, $thread, &$eventReturnValue]);
return $eventReturnValue;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadForum(array $data, \XF\Entity\Thread $thread)
{
return ($thread->node_id && in_array($thread->node_id, $data['forum_ids']));
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadPrefix(array $data, \XF\Entity\Thread $thread)
{
return ($thread->prefix_id && in_array($thread->prefix_id, $data['prefix_ids']));
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadReplyCount(array $data, \XF\Entity\Thread $thread)
{
return ($thread->reply_count && $thread->reply_count >= $data['messages']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadReplyCountMaximum(array $data, \XF\Entity\Thread $thread)
{
return ($thread->reply_count <= $data['messages']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadViewCount(array $data, \XF\Entity\Thread $thread)
{
return ($thread->view_count && $thread->view_count >= $data['amount']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadViewCountMaximum(array $data, \XF\Entity\Thread $thread)
{
return ($thread->view_count <= $data['amount']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadDiscussionState(array $data, \XF\Entity\Thread $thread)
{
return ($thread->discussion_state && $thread->discussion_state == $data['state']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadIsOpen(array $data, \XF\Entity\Thread $thread)
{
return (bool)$thread->discussion_open;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadNoOpen(array $data, \XF\Entity\Thread $thread)
{
return $thread->discussion_open ? false : true;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadIsSticky(array $data, \XF\Entity\Thread $thread)
{
return (bool)$thread->sticky;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadNoSticky(array $data, \XF\Entity\Thread $thread)
{
return $thread->sticky ? false : true;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterIsGuest(array $data, \XF\Entity\Thread $thread)
{
return ($thread->user_id == 0);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterIsMember(array $data, \XF\Entity\Thread $thread)
{
return ($thread->user_id > 0);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterIsModerator(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->User)
{
return false;
}
return (bool)$thread->User->is_moderator;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterIsAdmin(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->User)
{
return false;
}
return (bool)$thread->User->is_admin;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterTime(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->post_date)
{
return false;
}
$threadAge = floor((time() - $thread->post_date) / 86400);
if ($threadAge < $data['days'])
{
return false;
}
return true;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterLikeCount(array $data, \XF\Entity\Thread $thread)
{
return ($thread->first_post_likes && $thread->first_post_likes >= $data['likes']);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterUsername(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->username)
{
return false;
}
$names = preg_split('/\s*,\s*/', utf8_strtolower($data['names']), -1, PREG_SPLIT_NO_EMPTY);
return in_array(utf8_strtolower($thread->username), $names);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadStarterUsernameSearch(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->username)
{
return false;
}
if ($this->findNeedle($data['needles'], $thread->username) === false)
{
return false;
}
else
{
return true;
}
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyIsGuest(array $data, \XF\Entity\Thread $thread)
{
return ($thread->last_post_user_id == 0);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyIsMember(array $data, \XF\Entity\Thread $thread)
{
return ($thread->last_post_user_id > 0);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyIsStarter(array $data, \XF\Entity\Thread $thread)
{
return ($thread->last_post_user_id == $thread->user_id);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyIsModerator(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->LastPoster)
{
return false;
}
return (bool)$thread->LastPoster->is_moderator;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyIsAdmin(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->LastPoster)
{
return false;
}
return (bool)$thread->LastPoster->is_admin;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyTime(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->last_post_date)
{
return false;
}
$lastReplyAge = floor((time() - $thread->last_post_date) / 86400);
if ($lastReplyAge < $data['days'])
{
return false;
}
return true;
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyUsername(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->last_post_username)
{
return false;
}
$names = preg_split('/\s*,\s*/', utf8_strtolower($data['names']), -1, PREG_SPLIT_NO_EMPTY);
return in_array(utf8_strtolower($thread->last_post_username), $names);
}
/**
* @param array $data
* @param \XF\Entity\Thread $thread
*
* @return bool
*/
protected function _matchThreadLastReplyUsernameSearch(array $data, \XF\Entity\Thread $thread)
{
if (!$thread->last_post_username)
{
return false;
}
if ($this->findNeedle($data['needles'], $thread->last_post_username) === false)
{
return false;
}
else
{
return true;
}
}
/**
* @return array
*/
public function getExtraTemplateData()
{
$templateData = parent::getExtraTemplateData();
/** @var \XF\Repository\Node $nodeRepo */
$nodeRepo = $this->app->repository('XF:Node');
$nodes = $nodeRepo->createNodeTree($nodeRepo->getFullNodeList());
/** @var \XF\Repository\ThreadPrefix $prefixRepo */
$prefixRepo = \XF::repository('XF:ThreadPrefix');
$availablePrefixes = $prefixRepo->findPrefixesForList()->fetch()->pluckNamed('title', 'prefix_id');
$prefixListData = $prefixRepo->getPrefixListData();
$templateData = array_merge($templateData, [
'nodeTree' => $nodes,
'availablePrefixes' => $availablePrefixes,
'prefixGroups' => $prefixListData['prefixGroups'],
'prefixesGrouped' => $prefixListData['prefixesGrouped']
]);
return $templateData;
}
}