I've been working on adding an articles module to SimplePortal and realized that the permission system I designed for blocks and pages aren't very suitable when pagination is involved, which is a must when it comes to articles.
It's basically fetching a fixed number of rows from database without the information of whether you should fetch a particular row or not. Like, I need to fetch 5 articles per page but I cannot check if the user is allowed to view the article or not in the database query, only with a PHP function with the information that comes along with the rest of the article information.
function sp_get_articles()
{
global $smcFunc;
$request = $smcFunc['db_query']('','
SELECT id_article, permission_set, groups_allowed, groups_denied
FROM {db_prefix}sp_articles',
array()
);
$return = array();
while ($row = $smcFunc['db_fetch_assoc']($request))
{
if (!sp_allowed_to('article', $row['id_article'], $row['permission_set'], $row['groups_allowed'], $row['groups_denied']))
continue;
$return[] = array(
'id' => $row['id_article'],
);
}
$smcFunc['db_free_result']($request);
}
function sp_allowed_to($type, $id, $set = null, $allowed = null, $denied = null)
{
global $smcFunc, $user_info;
static $cache, $types;
if (!isset($types))
{
$types = array(
'article' => array(
'table' => 'articles',
'id' => 'id_article',
),
'block' => array(
'table' => 'blocks',
'id' => 'id_block',
),
'category' => array(
'table' => 'categories',
'id' => 'id_category',
),
'page' => array(
'table' => 'pages',
'id' => 'id_page',
),
'shoutbox' => array(
'table' => 'shoutboxes',
'id' => 'id_shoutbox',
),
);
}
if (empty($id) || empty($type) || !isset($types[$type]))
return false;
if (!isset($set, $allowed, $denied))
{
$request = $smcFunc['db_query']('','
SELECT permission_set, groups_allowed, groups_denied
FROM {db_prefix}sp_{raw:table}
WHERE {raw:id} = {int:id_item}
LIMIT {int:limit}',
array(
'table' => $types[$type]['table'],
'id' => $types[$type]['id'],
'id_item' => $id,
'limit' => 1,
)
);
list ($set, $allowed, $denied) = $smcFunc['db_fetch_row']($request);
$smcFunc['db_free_result']($request);
}
$result = false;
$cache_name = md5(implode(':', array($set, $allowed, $denied)));
if (isset($cache[$cache_name]))
$result = $cache[$cache_name];
else
{
switch ($set)
{
case 3:
$result = true;
break;
case 2:
$result = empty($user_info['is_guest']);
break;
case 1:
$result = !empty($user_info['is_guest']);
break;
case 0:
if (!empty($denied) && count(array_intersect($user_info['groups'], explode(',', $denied))) > 0)
$result = false;
elseif (!empty($allowed) && count(array_intersect($user_info['groups'], explode(',', $allowed))) > 0)
$result = true;
break;
default:
break;
}
$cache[$cache_name] = $result;
}
return $result;
}
I really don't want to change the permission system as it's very simple to use as an admin and account for every case I can think of. However, I'd rather change the permission system than fetching all the articles and limiting them with PHP. So I was wondering if anyone here has any ideas on how to add pagination while using the current permission system. Do you think it's possible and viable to make the check that sp_allowed_to() function does in a database query?