Example #1
0
/**
 * Create a new publication type
 *
 * @param $args['name'] name of the publication type
 * @param $args['descr'] description of the publication type
 * @param $args['config'] configuration of the publication type
 * @return int publication type ID on success, false on failure
 */
function publications_adminapi_createpubtype($args)
{
    // Get arguments from argument array
    extract($args);
    // Argument check - make sure that all required arguments are present
    // and in the right format, if not then set an appropriate error
    // message and return
    // Note : since we have several arguments we want to check here, we'll
    // report all those that are invalid at the same time...
    $invalid = array();
    if (!isset($name) || !is_string($name) || empty($name)) {
        $invalid[] = 'name';
    }
    if (!isset($config) || !is_array($config) || count($config) == 0) {
        $invalid[] = 'configuration';
    }
    if (count($invalid) > 0) {
        $msg = xarML('Invalid #(1) for #(2) function #(3)() in module #(4)', join(', ', $invalid), 'admin', 'createpubtype', 'Publications');
        throw new BadParameterException(null, $msg);
    }
    if (empty($descr)) {
        $descr = $name;
    }
    // Publication type names *must* be lower-case for now
    $name = strtolower($name);
    // Security check - we require ADMIN rights here
    if (!xarSecurityCheck('AdminPublications')) {
        return;
    }
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    // Make sure we have all the configuration fields we need
    $pubfields = xarModAPIFunc('publications', 'user', 'getpubfields');
    foreach ($pubfields as $field => $value) {
        if (!isset($config[$field])) {
            $config[$field] = '';
        }
    }
    // Get database setup
    $dbconn = xarDB::getConn();
    $xartable = xarDB::getTables();
    $pubtypestable = $xartable['publication_types'];
    // Get next ID in table
    $nextId = $dbconn->GenId($pubtypestable);
    // Insert the publication type
    $query = "INSERT INTO {$pubtypestable} (pubtype_id, pubtypename,\n            pubtypedescr, pubtypeconfig)\n            VALUES (?,?,?,?)";
    $bindvars = array($nextId, $name, $descr, serialize($config));
    $result =& $dbconn->Execute($query, $bindvars);
    if (!$result) {
        return;
    }
    // Get ptid to return
    $ptid = $dbconn->PO_Insert_ID($pubtypestable, 'pubtype_id');
    // Don't call creation hooks here...
    //xarModCallHooks('item', 'create', $ptid, 'ptid');
    return $ptid;
}
Example #2
0
/**
 * Delete a publication type
 *
 * @param $args['ptid'] ID of the publication type
 * @return bool true on success, false on failure
 */
function publications_adminapi_deletepubtype($args)
{
    // Get arguments from argument array
    extract($args);
    // Argument check - make sure that all required arguments are present
    // and in the right format, if not then set an appropriate error
    // message and return
    if (!isset($ptid) || !is_numeric($ptid) || $ptid < 1) {
        $msg = xarML('Invalid #(1) for #(2) function #(3)() in module #(4)', 'publication type ID', 'admin', 'deletepubtype', 'Publications');
        throw new BadParameterException(null, $msg);
    }
    // Security check - we require ADMIN rights here
    if (!xarSecurityCheck('AdminPublications', 1, 'Publication', "{$ptid}:All:All:All")) {
        return;
    }
    // Load user API to obtain item information function
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    // Get current publication types
    $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
    if (!isset($pubtypes[$ptid])) {
        $msg = xarML('Invalid #(1) for #(2) function #(3)() in module #(4)', 'publication type ID', 'admin', 'deletepubtype', 'Publications');
        throw new BadParameterException(null, $msg);
    }
    // Get database setup
    $dbconn = xarDB::getConn();
    $xartable = xarDB::getTables();
    $pubtypestable = $xartable['publication_types'];
    // Delete the publication type
    $query = "DELETE FROM {$pubtypestable}\n            WHERE pubtype_id = ?";
    $result =& $dbconn->Execute($query, array($ptid));
    if (!$result) {
        return;
    }
    $publicationstable = $xartable['publications'];
    // Delete all publications for this publication type
    $query = "DELETE FROM {$publicationstable}\n            WHERE pubtype_id = ?";
    $result =& $dbconn->Execute($query, array($ptid));
    if (!$result) {
        return;
    }
    // TODO: call some kind of itemtype delete hooks here, once we have those
    //xarModCallHooks('itemtype', 'delete', $ptid,
    //                array('module' => 'publications',
    //                      'itemtype' =>'ptid'));
    return true;
}
Example #3
0
/**
 * redirect to a site based on some URL field of the item
 */
function publications_user_redirect($args)
{
    // Get parameters from user
    if (!xarVarFetch('id', 'id', $id, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // Override if needed from argument array
    extract($args);
    if (!isset($id) || !is_numeric($id) || $id < 1) {
        return xarML('Invalid publication ID');
    }
    // Load API
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    // Get publication
    $publication = xarModAPIFunc('publications', 'user', 'get', array('id' => $id));
    if (!is_array($publication)) {
        $msg = xarML('Failed to retrieve publication in #(3)_#(1)_#(2).php', 'user', 'get', 'publications');
        throw new DataNotFoundException(null, $msg);
    }
    $ptid = $publication['pubtype_id'];
    // Get publication types
    $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
    // TODO: improve this e.g. when multiple URL fields are present
    // Find an URL field based on the pubtype configuration
    foreach ($pubtypes[$ptid]['config'] as $field => $value) {
        if (empty($value['label'])) {
            continue;
        }
        if ($value['format'] == 'url' && !empty($publication[$field]) && $publication[$field] != 'http://') {
            // TODO: add some verifications here !
            $hooks = xarModCallHooks('item', 'display', $id, array('module' => 'publications', 'itemtype' => $ptid), 'publications');
            xarController::redirect($article[$field]);
            return true;
        } elseif ($value['format'] == 'urltitle' && !empty($publication[$field]) && substr($publication[$field], 0, 2) == 'a:') {
            $array = unserialize($publication[$field]);
            if (!empty($array['link']) && $array['link'] != 'http://') {
                $hooks = xarModCallHooks('item', 'display', $id, array('module' => 'publications', 'itemtype' => $ptid), 'publications');
                xarController::redirect($array['link']);
                return true;
            }
        }
    }
    return xarML('Unable to find valid redirect field');
}
Example #4
0
/**
 * count number of items depending on additional module criteria
 *
 * @param $args['catid'] string of category id(s) that we're counting in, or
 * @param $args['cids'] array of cids that we are counting in (OR/AND)
 * @param $args['andcids'] true means AND-ing categories listed in cids
 *
 * @param $args['owner'] the ID of the author
 * @param $args['ptid'] publication type ID (for news, sections, reviews, ...)
 * @param $args['state'] array of requested status(es) for the publications
 * @param $args['startdate'] publications published at startdate or later
 *                           (unix timestamp format)
 * @param $args['enddate'] publications published before enddate
 *                         (unix timestamp format)
 * @return int number of items
 */
function publications_userapi_countitems($args)
{
    // Database information
    $dbconn = xarDB::getConn();
    // Get the field names and LEFT JOIN ... ON ... parts from publications
    // By passing on the $args, we can let leftjoin() create the WHERE for
    // the publications-specific columns too now
    $publicationsdef = xarModAPIFunc('publications', 'user', 'leftjoin', $args);
    // TODO: make sure this is SQL standard
    // Start building the query
    if ($dbconn->databaseType == 'sqlite') {
        $query = 'SELECT COUNT(*)
                  FROM ( SELECT DISTINCT ' . $publicationsdef['field'] . '
                         FROM ' . $publicationsdef['table'];
        // WATCH OUT, UNBALANCED
    } else {
        $query = 'SELECT COUNT(DISTINCT ' . $publicationsdef['field'] . ')';
        $query .= ' FROM ' . $publicationsdef['table'];
    }
    if (!isset($args['cids'])) {
        $args['cids'] = array();
    }
    if (!isset($args['andcids'])) {
        $args['andcids'] = false;
    }
    if (count($args['cids']) > 0 || !empty($args['catid'])) {
        // Load API
        if (!xarModAPILoad('categories', 'user')) {
            return;
        }
        // Get the LEFT JOIN ... ON ...  and WHERE (!) parts from categories
        $args['modid'] = xarModGetIDFromName('publications');
        if (isset($args['ptid']) && !isset($args['itemtype'])) {
            $args['itemtype'] = $args['ptid'];
        }
        $categoriesdef = xarModAPIFunc('categories', 'user', 'leftjoin', $args);
        $query .= ' LEFT JOIN ' . $categoriesdef['table'];
        $query .= ' ON ' . $categoriesdef['field'] . ' = ' . $publicationsdef['id'];
        $query .= $categoriesdef['more'];
        $docid = 1;
    }
    // Create the WHERE part
    $where = array();
    // we rely on leftjoin() to create the necessary publications clauses now
    if (!empty($publicationsdef['where'])) {
        $where[] = $publicationsdef['where'];
    }
    if (!empty($docid)) {
        // we rely on leftjoin() to create the necessary categories clauses
        $where[] = $categoriesdef['where'];
    }
    if (count($where) > 0) {
        $query .= ' WHERE ' . join(' AND ', $where);
    }
    // Balance parentheses
    if ($dbconn->databaseType == 'sqlite') {
        $query .= ')';
    }
    // Run the query - finally :-)
    $result =& $dbconn->Execute($query);
    if (!$result) {
        return;
    }
    if ($result->EOF) {
        return;
    }
    $num = $result->fields[0];
    $result->Close();
    return $num;
}
Example #5
0
/**
 * get the number of publications per publication type and category
 *
 * @param $args['state'] array of requested status(es) for the publications
 * @param $args['ptid'] publication type ID
 * @param $args['cids'] array of category IDs (OR/AND)
 * @param $args['andcids'] true means AND-ing categories listed in cids
 * @param $args['groupcids'] the number of categories you want items grouped by
 * @param $args['reverse'] default is ptid => cid, reverse (1) is cid => ptid
 * @return array array( $ptid => array( $cid => $count) ),
 *         or false on failure
 */
function publications_userapi_getpubcatcount($args)
{
    /*
        static $pubcatcount = array();
    
        if (count($pubcatcount) > 0) {
            return $pubcatcount;
        }
    */
    $pubcatcount = array();
    // Get database setup
    $dbconn = xarDB::getConn();
    // Get the LEFT JOIN ... ON ...  and WHERE parts from publications
    $publicationsdef = xarModAPIFunc('publications', 'user', 'leftjoin', $args);
    // Load API
    if (!xarModAPILoad('categories', 'user')) {
        return;
    }
    $args['modid'] = xarMod::getRegID('publications');
    if (isset($args['ptid']) && !isset($args['itemtype'])) {
        $args['itemtype'] = $args['ptid'];
    }
    // Get the LEFT JOIN ... ON ...  and WHERE parts from categories
    $categoriesdef = xarModAPIFunc('categories', 'user', 'leftjoin', $args);
    // Get count
    $query = 'SELECT ' . $publicationsdef['pubtype_id'] . ', ' . $categoriesdef['category_id'] . ', COUNT(*)
            FROM ' . $publicationsdef['table'] . '
            LEFT JOIN ' . $categoriesdef['table'] . '
            ON ' . $categoriesdef['field'] . ' = ' . $publicationsdef['field'] . $categoriesdef['more'] . '
            WHERE ' . $categoriesdef['where'] . ' AND ' . $publicationsdef['where'] . '
            GROUP BY ' . $publicationsdef['pubtype_id'] . ', ' . $categoriesdef['category_id'];
    $result =& $dbconn->Execute($query);
    if (!$result) {
        return;
    }
    if ($result->EOF) {
        if (!empty($args['ptid']) && empty($args['reverse'])) {
            $pubcatcount[$args['ptid']] = array();
        }
        return $pubcatcount;
    }
    while (!$result->EOF) {
        // we may have 1 or more cid fields here, depending on what we're
        // counting (cfr. AND in categories)
        $fields = $result->fields;
        $ptid = array_shift($fields);
        $count = array_pop($fields);
        // TODO: use multi-level array for multi-category grouping ?
        $cid = join('+', $fields);
        if (empty($args['reverse'])) {
            $pubcatcount[$ptid][$cid] = $count;
        } else {
            $pubcatcount[$cid][$ptid] = $count;
        }
        $result->MoveNext();
    }
    foreach ($pubcatcount as $id1 => $val) {
        $total = 0;
        foreach ($val as $id2 => $count) {
            $total += $count;
        }
        $pubcatcount[$id1]['total'] = $total;
    }
    return $pubcatcount;
}
Example #6
0
/**
 * search publications (called as hook from search module, or directly with pager)
 *
 * @param $args['objectid'] could be the query ? (currently unused)
 * @param $args['extrainfo'] all other parameters ? (currently unused)
 * @return array output
 */
function publications_user_search($args)
{
    // pager stuff
    if (!xarVarFetch('startnum', 'int:0', $startnum, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // categories stuff
    if (!xarVarFetch('cids', 'array', $cids, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('andcids', 'str', $andcids, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('catid', 'str', $catid, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // single publication type when called via the pager
    if (!xarVarFetch('ptid', 'id', $ptid, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // multiple publication types when called via search hooks
    if (!xarVarFetch('ptids', 'array', $ptids, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // date stuff via forms
    if (!xarVarFetch('publications_startdate', 'str', $startdate, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('publications_enddate', 'str', $enddate, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // date stuff via URLs
    if (!xarVarFetch('start', 'int:0', $start, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('end', 'int:0', $end, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // search button was pressed
    if (!xarVarFetch('search', 'str', $search, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // select by article state (array or string)
    if (!xarVarFetch('state', 'isset', $state, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // yes, this is the query
    if (!xarVarFetch('q', 'str', $q, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('author', 'str', $author, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // filter by category
    if (!xarVarFetch('by', 'str', $by, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // can't use list enum here, because we don't know which sorts might be used
    if (!xarVarFetch('sort', 'regexp:/^[\\w,]*$/', $sort, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    // boolean AND/OR for words (no longer used)
    //if(!xarVarFetch('bool',     'str',   $bool,   NULL, XARVAR_NOT_REQUIRED)) {return;}
    // search in specific fields
    if (!xarVarFetch('publications_fields', 'isset', $fields, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('searchtype', 'isset', $searchtype, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (isset($args['objectid'])) {
        $ishooked = 1;
    } else {
        $ishooked = 0;
        if (empty($fields)) {
            // search in specific fields via URLs
            if (!xarVarFetch('fields', 'isset', $fields, NULL, XARVAR_NOT_REQUIRED)) {
                return;
            }
        }
    }
    // TODO: could we need this someday ?
    if (isset($args['extrainfo'])) {
        extract($args['extrainfo']);
    }
    // TODO: clean up this copy & paste stuff :-)
    // Default parameters
    if (!isset($startnum)) {
        $startnum = 1;
    }
    if (!isset($numitems)) {
        $numitems = 20;
    }
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    // Get publication types
    $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
    if (xarSecurityCheck('AdminPublications', 0)) {
        $isadmin = true;
    } else {
        $isadmin = false;
    }
    // frontpage or approved state
    if (!$isadmin || !isset($state)) {
        $state = array(PUBLICATIONS_STATE_FRONTPAGE, PUBLICATIONS_STATE_APPROVED);
    } elseif (is_string($state)) {
        if (strpos($state, ' ')) {
            $state = explode(' ', $state);
        } elseif (strpos($state, '+')) {
            $state = explode('+', $state);
        } else {
            $state = array($state);
        }
    }
    $seenstate = array();
    foreach ($state as $that) {
        if (empty($that) || !is_numeric($that)) {
            continue;
        }
        $seenstate[$that] = 1;
    }
    $state = array_keys($seenstate);
    if (count($state) != 2 || !in_array(PUBLICATIONS_STATE_APPROVED, $state) || !in_array(PUBLICATIONS_STATE_FRONTPAGE, $state)) {
        $stateline = implode('+', $state);
    } else {
        $stateline = null;
    }
    if (!isset($sort)) {
        $sort = null;
    }
    // default publication type(s) to search in
    if (!empty($ptid) && isset($pubtypes[$ptid])) {
        $ptids = array($ptid);
        $settings = unserialize(xarModVars::get('publications', 'settings.' . $ptid));
        if (empty($settings['show_categories'])) {
            $show_categories = 0;
        } else {
            $show_categories = 1;
        }
    } elseif (!empty($ptids) && count($ptids) > 0) {
        foreach ($ptids as $curptid) {
            // default view doesn't apply here ?!
        }
        $show_categories = 1;
    } elseif (!isset($ptids)) {
        //    $ptids = array(xarModVars::get('publications','defaultpubtype'));
        $ptids = array();
        foreach ($pubtypes as $pubid => $pubtype) {
            $ptids[] = $pubid;
        }
        $show_categories = 1;
    } else {
        // TODO: rethink this when we're dealing with multi-pubtype categories
        $show_categories = 0;
    }
    // turn $catid into $cids array (and set $andcids flag)
    if (!empty($catid)) {
        if (strpos($catid, ' ')) {
            $cids = explode(' ', $catid);
            $andcids = true;
        } elseif (strpos($catid, '+')) {
            $cids = explode('+', $catid);
            $andcids = true;
        } else {
            $cids = explode('-', $catid);
            $andcids = false;
        }
    }
    $seencid = array();
    $catid = null;
    if (isset($cids) && is_array($cids)) {
        foreach ($cids as $cid) {
            if (empty($cid) || !preg_match('/^_?[0-9]+$/', $cid)) {
                continue;
            }
            $seencid[$cid] = 1;
        }
        $cids = array_keys($seencid);
        if ($andcids) {
            $catid = join('+', $cids);
        } else {
            $catid = join('-', $cids);
        }
    }
    $seenptid = array();
    if (isset($ptids) && is_array($ptids)) {
        foreach ($ptids as $curptid) {
            if (empty($curptid) || !isset($pubtypes[$curptid])) {
                continue;
            }
            $seenptid[$curptid] = 1;
        }
        $ptids = array_keys($seenptid);
    }
    /* Ensure whitespace alone not passed to api -causes errors */
    if (isset($q) && trim($q) === '') {
        $q = null;
    }
    // Find the id of the author we're looking for
    if (!empty($author)) {
        // Load API
        if (!xarModAPILoad('roles', 'user')) {
            return;
        }
        $user = xarModAPIFunc('roles', 'user', 'get', array('name' => $author));
        if (!empty($user['uid'])) {
            $owner = $user['uid'];
        } else {
            $owner = null;
            $author = null;
        }
    } else {
        $owner = null;
        $author = null;
    }
    if (isset($start) && is_numeric($start)) {
        $startdate = xarLocaleFormatDate("%Y-%m-%d %H:%M:%S", $start);
    }
    if (isset($end) && is_numeric($end)) {
        $enddate = xarLocaleFormatDate("%Y-%m-%d %H:%M:%S", $end);
    }
    if (empty($fields)) {
        $fieldlist = array('title', 'description', 'summary', 'body1');
    } else {
        $fieldlist = array_keys($fields);
        // don't pass fields via URLs if we stick to the default list
        if (count($fields) == 3 && isset($fields['title']) && isset($fields['description']) && isset($fields['summary']) && isset($fields['body1'])) {
            $fields = null;
        }
    }
    // Set default searchtype to 'fulltext' if necessary
    $fulltext = xarModVars::get('publications', 'fulltextsearch');
    if (!isset($searchtype) && !empty($fulltext)) {
        $searchtype = 'fulltext';
    }
    // FIXME: fulltext only supports searching in all configured text fields !
    if (empty($fields) && !empty($fulltext) && !empty($searchtype) && $searchtype == 'fulltext') {
        $fieldlist = explode(',', $fulltext);
    }
    $data = array();
    $data['results'] = array();
    $data['state'] = '';
    $data['ishooked'] = $ishooked;
    // TODO: MichelV: $ishooked is never empty, but either 0 or 1
    if (empty($ishooked)) {
        $data['q'] = isset($q) ? xarVarPrepForDisplay($q) : null;
        $data['author'] = isset($author) ? xarVarPrepForDisplay($author) : null;
        $data['searchtype'] = $searchtype;
    }
    if ($isadmin) {
        $states = xarModAPIFunc('publications', 'user', 'getstates');
        $data['statelist'] = array();
        foreach ($states as $id => $name) {
            $data['statelist'][] = array('id' => $id, 'name' => $name, 'checked' => in_array($id, $state));
        }
    }
    // TODO: show field labels when we're dealing with only 1 pubtype
    $data['fieldlist'] = array(array('id' => 'title', 'name' => xarML('title'), 'checked' => in_array('title', $fieldlist)), array('id' => 'description', 'name' => xarML('description'), 'checked' => in_array('description', $fieldlist)), array('id' => 'summary', 'name' => xarML('summary'), 'checked' => in_array('summary', $fieldlist)), array('id' => 'body1', 'name' => xarML('body1'), 'checked' => in_array('body1', $fieldlist)), array('id' => 'notes', 'name' => xarML('notes'), 'checked' => in_array('notes', $fieldlist)));
    $data['publications'] = array();
    foreach ($pubtypes as $pubid => $pubtype) {
        if (!empty($seenptid[$pubid])) {
            $checked = ' checked="checked"';
        } else {
            $checked = '';
        }
        $data['publications'][] = array('id' => $pubid, 'description' => xarVarPrepForDisplay($pubtype['description']), 'checked' => $checked);
    }
    $data['categories'] = array();
    if (!empty($by) && $by == 'cat') {
        $catarray = array();
        foreach ($ptids as $curptid) {
            // get root categories for this publication type
            $catlinks = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications', 'itemtype' => $curptid));
            foreach ($catlinks as $cat) {
                $catarray[$cat['category_id']] = $cat['name'];
            }
        }
        foreach ($catarray as $cid => $title) {
            $select = xarModAPIFunc('categories', 'visual', 'makeselect', array('cid' => $cid, 'return_itself' => true, 'select_itself' => true, 'values' => &$seencid, 'multiple' => 1));
            $data['categories'][] = array('cattitle' => $title, 'catselect' => $select);
        }
        $data['searchurl'] = xarModURL('search', 'user', 'main');
    } else {
        $data['searchurl'] = xarModURL('search', 'user', 'main', array('by' => 'cat'));
    }
    $now = time();
    if (empty($startdate)) {
        $startdate = null;
        $data['startdate'] = 'N/A';
    } else {
        if (!preg_match('/[a-zA-Z]+/', $startdate)) {
            $startdate .= ' GMT';
        }
        $startdate = strtotime($startdate);
        // adjust for the user's timezone offset
        $startdate -= xarMLS_userOffset() * 3600;
        if ($startdate > $now && !$isadmin) {
            $startdate = $now;
        }
        $data['startdate'] = $startdate;
    }
    if (empty($enddate)) {
        $enddate = $now;
        $data['enddate'] = 'N/A';
    } else {
        if (!preg_match('/[a-zA-Z]+/', $enddate)) {
            $enddate .= ' GMT';
        }
        $enddate = strtotime($enddate);
        // adjust for the user's timezone offset
        $enddate -= xarMLS_userOffset() * 3600;
        if ($enddate > $now && !$isadmin) {
            $enddate = $now;
        }
        $data['enddate'] = $enddate;
    }
    if (!empty($q) || !empty($author) && isset($owner) || !empty($search) || !empty($ptid) || !empty($startdate) || $enddate != $now || !empty($catid)) {
        $getfields = array('id', 'title', 'start_date', 'pubtype_id', 'cids');
        // Return the relevance when using MySQL full-text search
        //if (!empty($search) && !empty($searchtype) && substr($searchtype,0,8) == 'fulltext') {
        //    $getfields[] = 'relevance';
        //}
        $count = 0;
        // TODO: allow combination of searches ?
        foreach ($ptids as $curptid) {
            $publications = xarModAPIFunc('publications', 'user', 'getall', array('startnum' => $startnum, 'cids' => $cids, 'andcids' => $andcids, 'ptid' => $curptid, 'owner' => $owner, 'sort' => $sort, 'numitems' => $numitems, 'state' => $state, 'start_date' => $startdate, 'end_date' => $enddate, 'searchfields' => $fieldlist, 'searchtype' => $searchtype, 'search' => $q, 'fields' => $getfields));
            // TODO: re-use article output code from elsewhere (view / archive / admin)
            if (!empty($publications) && count($publications) > 0) {
                // retrieve the categories for each article
                $catinfo = array();
                if ($show_categories) {
                    $cidlist = array();
                    foreach ($publications as $article) {
                        if (!empty($article['cids']) && count($article['cids']) > 0) {
                            foreach ($article['cids'] as $cid) {
                                $cidlist[$cid] = 1;
                            }
                        }
                    }
                    if (count($cidlist) > 0) {
                        $catinfo = xarModAPIFunc('categories', 'user', 'getcatinfo', array('cids' => array_keys($cidlist)));
                        // get root categories for this publication type
                        $catroots = xarModAPIFunc('publications', 'user', 'getrootcats', array('ptid' => $curptid));
                        $catroots = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications', 'itemtype' => $curptid));
                    }
                    foreach ($catinfo as $cid => $info) {
                        $catinfo[$cid]['name'] = xarVarPrepForDisplay($info['name']);
                        $catinfo[$cid]['link'] = xarModURL('publications', 'user', 'view', array('ptid' => $curptid, 'catid' => $catid && $andcids ? $catid . '+' . $cid : $cid));
                        // only needed when sorting by root category id
                        $catinfo[$cid]['root'] = 0;
                        // means not found under a root category
                        // only needed when sorting by root category order
                        $catinfo[$cid]['order'] = 0;
                        // means not found under a root category
                        $rootidx = 1;
                        foreach ($catroots as $rootcat) {
                            // see if we're a child category of this rootcat (cfr. Celko model)
                            if ($info['left'] >= $rootcat['left_id'] && $info['left'] < $rootcat['right_id']) {
                                // only needed when sorting by root category id
                                $catinfo[$cid]['root'] = $rootcat['category_id'];
                                // only needed when sorting by root category order
                                $catinfo[$cid]['order'] = $rootidx;
                                break;
                            }
                            $rootidx++;
                        }
                    }
                }
                // needed for sort function below
                $GLOBALS['artsearchcatinfo'] = $catinfo;
                $items = array();
                foreach ($publications as $article) {
                    $count++;
                    $curptid = $article['pubtype_id'];
                    $link = xarModURL('publications', 'user', 'display', array('ptid' => $article['pubtype_id'], 'itemid' => $article['id']));
                    // publication date of article (if needed)
                    if (!empty($pubtypes[$curptid]['config']['startdate']['label']) && !empty($article['startdate'])) {
                        $date = xarLocaleFormatDate('%a, %d %B %Y %H:%M:%S %Z', $article['startdate']);
                        $startdate = $article['startdate'];
                    } else {
                        $date = '';
                        $startdate = 0;
                    }
                    if (empty($article['title'])) {
                        $article['title'] = xarML('(none)');
                    }
                    // categories this article belongs to
                    $categories = array();
                    if ($show_categories && !empty($article['cids']) && is_array($article['cids']) && count($article['cids']) > 0) {
                        $cidlist = $article['cids'];
                        // order cids by root category order
                        usort($cidlist, 'publications_search_sortbyorder');
                        // order cids by root category id
                        //usort($cidlist,'publications_search_sortbyroot');
                        // order cids by position in Celko tree
                        //usort($cidlist,'publications_search_sortbyleft');
                        $join = '';
                        foreach ($cidlist as $cid) {
                            $item = array();
                            if (!isset($catinfo[$cid])) {
                                // oops
                                continue;
                            }
                            $categories[] = array('cname' => $catinfo[$cid]['name'], 'clink' => $catinfo[$cid]['link'], 'cjoin' => $join);
                            if (empty($join)) {
                                $join = ' | ';
                            }
                        }
                    }
                    $items[] = array('title' => xarVarPrepHTMLDisplay($article['title']), 'link' => $link, 'date' => $date, 'startdate' => $startdate, 'relevance' => isset($article['relevance']) ? $article['relevance'] : null, 'categories' => $categories);
                }
                unset($publications);
                // Pager
                // TODO: make count depend on locale in the future
                sys::import('modules.base.class.pager');
                $pager = xarTplPager::getPager($startnum, xarModAPIFunc('publications', 'user', 'countitems', array('cids' => $cids, 'andcids' => $andcids, 'ptid' => $curptid, 'owner' => $owner, 'state' => $state, 'startdate' => $startdate, 'enddate' => $enddate, 'searchfields' => $fieldlist, 'searchtype' => $searchtype, 'search' => $q)), xarModURL('publications', 'user', 'search', array('ptid' => $curptid, 'catid' => $catid, 'q' => isset($q) ? $q : null, 'author' => isset($author) ? $author : null, 'start' => $startdate, 'end' => $enddate != $now ? $enddate : null, 'state' => $stateline, 'sort' => $sort, 'fields' => $fields, 'searchtype' => !empty($searchtype) ? $searchtype : null, 'startnum' => '%%')), $numitems);
                if (strlen($pager) > 5) {
                    if (!isset($sort) || $sort == 'date') {
                        $othersort = 'title';
                    } else {
                        $othersort = null;
                    }
                    $sortlink = xarModURL('publications', 'user', 'search', array('ptid' => $curptid, 'catid' => $catid, 'q' => isset($q) ? $q : null, 'author' => isset($author) ? $author : null, 'start' => $startdate, 'end' => $enddate != $now ? $enddate : null, 'state' => $stateline, 'fields' => $fields, 'searchtype' => !empty($searchtype) ? $searchtype : null, 'sort' => $othersort));
                    if (!isset($othersort)) {
                        $othersort = 'date';
                    }
                    $pager .= '&#160;&#160;<a href="' . $sortlink . '">' . xarML('sort by') . ' ' . xarML($othersort) . '</a>';
                }
                $data['results'][] = array('description' => xarVarPrepForDisplay($pubtypes[$curptid]['description']), 'items' => $items, 'pager' => $pager);
            }
        }
        unset($catinfo);
        unset($items);
        unset($GLOBALS['artsearchcatinfo']);
        if ($count > 0) {
            // bail out, we have what we needed
            return xarTplModule('publications', 'user', 'search', $data);
        }
        $data['state'] = xarML('No pages found matching this search');
    }
    return xarTplModule('publications', 'user', 'search', $data);
}
Example #7
0
/**
* check security for a particular article
*
* @param $args['mask'] the requested security mask
*
* @param $args['article'] the article array (if already retrieved)
* @param $args['id'] the article ID (if known, and article array not
                      already retrieved)
* @param $args['owner'] the user ID of the author (if not already included)
* @param $args['ptid'] the publication type ID (if not already included)
* @param $args['cids'] array of additional required category checks
*
* @return bool true if OK, false if not OK
*/
function publications_userapi_checksecurity($args)
{
    // Get arguments from argument array
    extract($args);
    // Compatibility mode with old API params - remove later
    if (isset($access) && !isset($mask)) {
        switch ($access) {
            case ACCESS_OVERVIEW:
                $mask = 'ViewPublications';
                break;
            case ACCESS_READ:
                $mask = 'ReadPublications';
                break;
            case ACCESS_COMMENT:
                $mask = 'SubmitPublications';
                break;
            case ACCESS_EDIT:
                $mask = 'EditPublications';
                break;
            case ACCESS_DELETE:
                $mask = 'ManagePublications';
                break;
            case ACCESS_ADMIN:
                $mask = 'AdminPublications';
                break;
            default:
                $mask = '';
        }
    }
    if (empty($mask)) {
        return false;
    }
    // Get article information
    if (!isset($publication) && !empty($id) && $mask != 'SubmitPublications') {
        $publication = xarModAPIFunc('publications', 'user', 'get', array('id' => $id, 'withcids' => true));
        if ($publication == false) {
            return false;
        }
    }
    if (empty($id) && isset($publication['id'])) {
        $id = $publication['id'];
    }
    if (!isset($id)) {
        $id = '';
    }
    // Get author ID
    if (isset($publication['owner']) && empty($owner)) {
        $owner = $publication['owner'];
    }
    // Get state
    if (isset($publication['state']) && !isset($state)) {
        $state = $publication['state'];
    }
    if (empty($state)) {
        $state = 0;
    }
    // reject reading access to unapproved publications
    if ($state < 2 && ($mask == 'ViewPublications' || $mask == 'ReadPublications')) {
        return false;
    }
    // Get publication type ID
    if (isset($publication['pubtype_id'])) {
        if (!isset($ptid)) {
            $ptid = $publication['pubtype_id'];
        } elseif ($ptid != $publication['pubtype_id'] && $mask != 'EditPublications') {
            return false;
        }
    }
    // Get root categories for this publication type
    if (!empty($ptid)) {
        $rootcats = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications', 'itemtype' => $ptid));
    } else {
        $ptid = null;
    }
    if (!isset($rootcids)) {
        // TODO: handle cross-pubtype views better
        $rootcats = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications'));
    }
    // Get category information for this article
    if (!isset($publication['cids']) && !empty($id)) {
        if (!xarModAPILoad('categories', 'user')) {
            return;
        }
        $info = xarMod::getBaseInfo('publications');
        $sysid = $info['systemid'];
        $publicationcids = xarModAPIFunc('categories', 'user', 'getlinks', array('iids' => array($id), 'itemtype' => $ptid, 'modid' => $sysid, 'reverse' => 0));
        if (is_array($publicationcids) && count($publicationcids) > 0) {
            $publication['cids'] = array_keys($publicationcids);
        }
    }
    if (!isset($publication['cids'])) {
        $publication['cids'] = array();
    }
    if (!isset($cids)) {
        $cids = array();
    }
    $jointcids = array();
    /* TODO: forget about parent/root cids for now
        foreach ($rootcids as $cid) {
            $jointcids[$cid] = 1;
        }
    */
    foreach ($publication['cids'] as $cid) {
        $jointcids[$cid] = 1;
    }
    // FIXME: the line within the foreach is known to give an illegal offset error, not sure how to properly
    // fix it. Only seen on using xmlrpc and bloggerapi.
    foreach ($cids as $cid) {
        if (empty($cid) || !is_numeric($cid)) {
            continue;
        }
        $jointcids[$cid] = 1;
    }
    // TODO 1: find a way to combine checking over several categories
    // TODO 2: find a way to check parent categories for privileges too
    // TODO 3: find a way to specify current user in privileges too
    // TODO 4: find a way to check parent groups of authors for privileges too ??
    if (empty($ptid)) {
        $ptid = 'All';
    }
    if (count($jointcids) == 0) {
        $jointcids['All'] = 1;
    }
    // TODO: check for anonymous publications
    if (!isset($owner)) {
        $owner = 'All';
    }
    if (empty($id)) {
        $id = 'All';
    }
    // Loop over all categories and check the different combinations
    $result = false;
    foreach (array_keys($jointcids) as $cid) {
        // TODO: do we want all-or-nothing access here, or is one access enough ?
        if (xarSecurityCheck($mask, 0, 'Publication', "{$ptid}:{$cid}:{$owner}:{$id}")) {
            $result = true;
        }
    }
    return $result;
}
Example #8
0
/**
 * get an array of root categories with links
 *
 * @param int $args['ptid'] publication type ID
 * @param $args['all'] boolean if we need to return all root categories when
 *                     ptid is empty (default false)
 * @return array
 * @TODO specify return format
 */
function publications_userapi_getrootcats($args)
{
    extract($args);
    if (empty($ptid) || !is_numeric($ptid)) {
        $ptid = null;
    }
    // see which root categories we need to handle
    $rootcats = array();
    if (!empty($ptid)) {
        $rootcats = unserialize(xarModUserVars::get('publications', 'basecids', $ptid));
    } elseif (empty($all)) {
        $rootcats = unserialize(xarModVars::get('publications', 'basecids'));
    } else {
        // Get publication types
        $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
        // get base categories for all publication types here
        $publist = array_keys($pubtypes);
        // add the defaults too, in case we have other base categories there
        $publist[] = '';
        // build the list of root categories for all required publication types
        $catlist = array();
        foreach ($publist as $pubid) {
            if (empty($pubid)) {
                $cidstring = xarModVars::get('publications', 'basecids');
            } else {
                $cidstring = xarModUserVars::get('publications', 'basecids', $pubid);
            }
            if (!empty($cidstring)) {
                $rootcats = unserialize($cidstring);
            } else {
                $rootcats = array();
            }
            foreach ($rootcats as $cid) {
                $catlist[$cid] = 1;
            }
        }
        if (count($catlist) > 0) {
            $rootcats = array_keys($catlist);
        }
    }
    if (empty($rootcats)) {
        $rootcats = array();
    }
    if (count($rootcats) < 1) {
        return array();
    }
    if (!xarModAPILoad('categories', 'user')) {
        return;
    }
    $isfirst = 1;
    $catlinks = array();
    $catlist = xarModAPIFunc('categories', 'user', 'getcatinfo', array('cids' => $rootcats));
    if (empty($catlist)) {
        return $catlinks;
    }
    // preserve order of root categories if possible
    foreach ($rootcats as $cid) {
        if (!isset($catlist[$cid])) {
            continue;
        }
        $info = $catlist[$cid];
        $item = array();
        $item['catid'] = $info['cid'];
        $item['cattitle'] = xarVarPrepForDisplay($info['name']);
        $item['catlink'] = xarModURL('publications', 'user', 'view', array('ptid' => $ptid, 'catid' => $info['cid']));
        if ($isfirst) {
            $item['catjoin'] = '';
            $isfirst = 0;
        } else {
            $item['catjoin'] = ' | ';
        }
        $item['catleft'] = $info['left'];
        $item['catright'] = $info['right'];
        $catlinks[] = $item;
    }
    return $catlinks;
}
Example #9
0
/**
 * show monthly archive (Archives-like)
 */
function publications_user_archive($args)
{
    // Get parameters from user
    if (!xarVarFetch('ptid', 'id', $ptid, xarModVars::get('publications', 'defaultpubtype'), XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('sort', 'enum:d:t:1:2', $sort, 'd', XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('month', 'str', $month, '', XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('cids', 'array', $cids, NULL, XARVAR_NOT_REQUIRED)) {
        return;
    }
    if (!xarVarFetch('catid', 'str', $catid, '', XARVAR_NOT_REQUIRED)) {
        return;
    }
    // Override if needed from argument array
    extract($args);
    // Get publication types
    $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
    // Check that the publication type is valid
    if (empty($ptid) || !isset($pubtypes[$ptid])) {
        $ptid = null;
    }
    if (empty($ptid)) {
        if (!xarSecurityCheck('ViewPublications', 0, 'Publication', 'All:All:All:All')) {
            return xarML('You have no permission to view these items');
        }
    } elseif (!xarSecurityCheck('ViewPublications', 0, 'Publication', $ptid . ':All:All:All')) {
        return xarML('You have no permission to view these items');
    }
    $state = array(PUBLICATIONS_STATE_FRONTPAGE, PUBLICATIONS_STATE_APPROVED);
    $seencid = array();
    $andcids = false;
    // turn $catid into $cids array and set $andcids flag
    if (!empty($catid)) {
        if (strpos($catid, ' ')) {
            $cids = explode(' ', $catid);
            $andcids = true;
        } elseif (strpos($catid, '+')) {
            $cids = explode('+', $catid);
            $andcids = true;
        } elseif (strpos($catid, '-')) {
            $cids = explode('-', $catid);
            $andcids = false;
        } else {
            $cids = array($catid);
            if (strstr($catid, '_')) {
                $andcids = false;
                // don't combine with current category
            } else {
                $andcids = true;
            }
        }
    }
    if (isset($cids) && is_array($cids)) {
        foreach ($cids as $cid) {
            if (!empty($cid) && preg_match('/^_?[0-9]+$/', $cid)) {
                $seencid[$cid] = 1;
            }
        }
        $cids = array_keys($seencid);
        sort($cids, SORT_NUMERIC);
        if (empty($catid) && count($cids) > 1) {
            $andcids = true;
        }
    } else {
        $cids = null;
    }
    // QUESTION: work with user-dependent time settings or not someday ?
    // Set the start and end date for that month
    if (!empty($month) && preg_match('/^(\\d{4})-(\\d+)$/', $month, $matches)) {
        $startdate = gmmktime(0, 0, 0, $matches[2], 1, $matches[1]);
        // PHP allows month > 12 :-)
        $enddate = gmmktime(0, 0, 0, $matches[2] + 1, 1, $matches[1]);
        if ($enddate > time()) {
            $enddate = time();
        }
    } else {
        $startdate = '';
        $enddate = time();
        if (!empty($month) && $month != 'all') {
            $month = '';
        }
    }
    // Load API
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    if (!empty($ptid) && !empty($pubtypes[$ptid]['config']['pubdate']['label'])) {
        $showdate = 1;
    } else {
        $showdate = 0;
        foreach (array_keys($pubtypes) as $pubid) {
            if (!empty($pubtypes[$pubid]['config']['pubdate']['label'])) {
                $showdate = 1;
                break;
            }
        }
    }
    // Get monthly statistics
    $monthcount = xarModAPIFunc('publications', 'user', 'getmonthcount', array('ptid' => $ptid, 'state' => $state, 'enddate' => time()));
    if (empty($monthcount)) {
        $monthcount = array();
    }
    krsort($monthcount);
    reset($monthcount);
    $months = array();
    $total = 0;
    foreach ($monthcount as $thismonth => $count) {
        if ($thismonth == $month) {
            $mlink = '';
        } else {
            $mlink = xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => $thismonth));
        }
        $months[] = array('month' => $thismonth, 'mcount' => $count, 'mlink' => $mlink);
        $total += $count;
    }
    if (empty($ptid)) {
        $thismonth = xarML('All Publications');
    } else {
        $thismonth = xarML('All') . ' ' . $pubtypes[$ptid]['description'];
    }
    if ($month == 'all') {
        $mlink = '';
    } else {
        $mlink = xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => 'all'));
    }
    $months[] = array('month' => $thismonth, 'mcount' => $total, 'mlink' => $mlink);
    // Load API
    if (!xarModAPILoad('categories', 'user')) {
        return;
    }
    // Get the list of root categories for this publication type
    if (!empty($ptid)) {
        $rootcats = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications', 'itemtype' => $ptid));
    } else {
        $rootcats = xarModAPIFunc('categories', 'user', 'getallcatbases', array('module' => 'publications', 'itemtype' => 0));
    }
    $catlist = array();
    $catinfo = array();
    $catsel = array();
    if (!empty($rootcats)) {
        // TODO: do this in categories API ?
        $count = 1;
        foreach ($rootcats as $cid) {
            if (empty($cid)) {
                continue;
            }
            // save the name and root category for each child
            $cats = xarModAPIFunc('categories', 'user', 'getcat', array('cid' => $cid['category_id'], 'return_itself' => true, 'getchildren' => true));
            foreach ($cats as $info) {
                $item = array();
                $item['name'] = $info['name'];
                $item['root'] = $cid['category_id'];
                $catinfo[$info['cid']] = $item;
            }
            // don't allow sorting by category when viewing all publications
            //if ($sort == $count || $month == 'all') {
            if ($sort == $count) {
                $link = '';
            } else {
                $link = xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => $month, 'sort' => $count));
            }
            // catch more faulty categories assignments
            if (isset($catinfo[$cid['category_id']])) {
                $catlist[] = array('cid' => $cid['category_id'], 'name' => $catinfo[$cid['category_id']]['name'], 'link' => $link);
                $catsel[] = xarModAPIFunc('categories', 'visual', 'makeselect', array('cid' => $cid['category_id'], 'return_itself' => true, 'select_itself' => true, 'values' => &$seencid, 'multiple' => 0));
                $count++;
            }
        }
    }
    // Get publications
    if ($month == 'all' || $startdate && $enddate) {
        $publications = xarModAPIFunc('publications', 'user', 'getall', array('ptid' => isset($ptid) ? $ptid : null, 'startdate' => $startdate, 'enddate' => $enddate, 'state' => $state, 'cids' => $cids, 'andcids' => $andcids, 'fields' => array('id', 'title', 'start_date', 'pubtype_id', 'cids')));
        if (!is_array($publications)) {
            $msg = xarML('Failed to retrieve publications in #(3)_#(1)_#(2).php', 'user', 'getall', 'publications');
            throw new DataNotFoundException(null, $msg);
        }
    } else {
        $publications = array();
    }
    // TODO: add print / recommend_us link for each article ?
    // TODO: add view count to table/query/template someday ?
    foreach ($publications as $key => $article) {
        $publications[$key]['link'] = xarModURL('publications', 'user', 'display', array('ptid' => isset($ptid) ? $publications[$key]['pubtype_id'] : null, 'id' => $publications[$key]['id']));
        if (empty($publications[$key]['title'])) {
            $publications[$key]['title'] = xarML('(none)');
        }
        /* TODO: move date formatting to template, delete this code after testing
                if ($showdate && !empty($publications[$key]['pubdate'])) {
                    $publications[$key]['date'] = xarLocaleFormatDate("%Y-%m-%d %H:%M:%S",
                                                       $publications[$key]['pubdate']);
                } else {
                    $publications[$key]['date'] = '';
                }
        */
        // TODO: find some better way to do this...
        $list = array();
        // get all the categories for that article and put them under the
        // right root category
        if (!isset($publications[$key]['cids'])) {
            $publications[$key]['cids'] = array();
        }
        foreach ($publications[$key]['cids'] as $cid) {
            // skip unknown categories (e.g. when not under root categories)
            if (!isset($catinfo[$cid])) {
                continue;
            }
            if (!isset($list[$catinfo[$cid]['root']])) {
                $list[$catinfo[$cid]['root']] = array();
            }
            array_push($list[$catinfo[$cid]['root']], $cid);
        }
        // fill in the column corresponding to each root category
        $publications[$key]['cats'] = array();
        foreach ($catlist as $cat) {
            if (isset($list[$cat['cid']])) {
                $descr = '';
                // TODO: add links to category someday ?
                foreach ($list[$cat['cid']] as $cid) {
                    if (!empty($descr)) {
                        $descr .= '<br />';
                    }
                    $descr .= $catinfo[$cid]['name'];
                }
                $publications[$key]['cats'][] = array('list' => $descr);
            } else {
                $publications[$key]['cats'][] = array('list' => '-');
            }
        }
    }
    // sort publications as requested
    if ($sort == 2 && count($catlist) > 1) {
        usort($publications, 'publications_archive_sortbycat10');
    } elseif ($sort == 1) {
        if (count($catlist) > 1) {
            usort($publications, 'publications_archive_sortbycat01');
        } elseif (count($catlist) > 0) {
            usort($publications, 'publications_archive_sortbycat0');
        }
    } elseif ($sort == 't') {
        usort($publications, 'publications_archive_sortbytitle');
    } else {
        $sort = 'd';
        // default sort by date is already done in getall() function
    }
    // add title header
    if ($sort == 't') {
        $link = '';
    } else {
        $link = xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => $month, 'sort' => 't'));
    }
    $catlist[] = array('cid' => 0, 'name' => xarML('Title'), 'link' => $link);
    $catsel[] = '<input type="submit" value="' . xarML('Filter') . '" />';
    if ($showdate) {
        // add date header
        if ($sort == 'd') {
            $link = '';
        } else {
            $link = xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => $month));
        }
        $catlist[] = array('cid' => 0, 'name' => xarML('Date'), 'link' => $link);
        $catsel[] = '&#160;';
    }
    // Save some variables to (temporary) cache for use in blocks etc.
    xarVarSetCached('Blocks.publications', 'ptid', $ptid);
    if (!empty($cids)) {
        xarVarSetCached('Blocks.publications', 'cids', $cids);
    }
    //if ($shownavigation) {
    xarVarSetCached('Blocks.categories', 'module', 'publications');
    xarVarSetCached('Blocks.categories', 'itemtype', $ptid);
    if (!empty($ptid) && !empty($pubtypes[$ptid]['description'])) {
        xarVarSetCached('Blocks.categories', 'title', $pubtypes[$ptid]['description']);
        xarTplSetPageTitle(xarML('Archive'), $pubtypes[$ptid]['description']);
    } else {
        xarTplSetPageTitle(xarML('Archive'));
    }
    //}
    if (!empty($ptid)) {
        $settings = unserialize(xarModVars::get('publications', 'settings.' . $ptid));
    } else {
        $string = xarModVars::get('publications', 'settings');
        if (!empty($string)) {
            $settings = unserialize($string);
        }
    }
    if (!isset($show_publinks)) {
        if (!empty($settings['show_publinks'])) {
            $show_publinks = 1;
        } else {
            $show_publinks = 0;
        }
    }
    // show the number of publications for each publication type
    if (!isset($show_pubcount)) {
        if (!isset($settings['show_pubcount']) || !empty($settings['show_pubcount'])) {
            $show_pubcount = 1;
            // default yes
        } else {
            $show_pubcount = 0;
        }
    }
    //    $show_catcount = 0; // unused here
    // return template out
    $data = array('months' => $months, 'publications' => $publications, 'catlist' => $catlist, 'catsel' => $catsel, 'ptid' => $ptid, 'month' => $month, 'curlink' => xarModURL('publications', 'user', 'archive', array('ptid' => $ptid, 'month' => $month, 'sort' => $sort)), 'showdate' => $showdate, 'show_publinks' => $show_publinks, 'publabel' => xarML('Publication'), 'publinks' => xarModAPIFunc('publications', 'user', 'getpublinks', array('ptid' => $ptid, 'state' => array(PUBLICATIONS_STATE_FRONTPAGE, PUBLICATIONS_STATE_APPROVED), 'count' => $show_pubcount, 'func' => 'archive')), 'maplabel' => xarML('View Publication Map'), 'maplink' => xarModURL('publications', 'user', 'viewmap', array('ptid' => $ptid)), 'viewlabel' => empty($ptid) ? xarML('Back to Publications') : xarML('Back to') . ' ' . $pubtypes[$ptid]['description'], 'viewlink' => xarModURL('publications', 'user', 'view', array('ptid' => $ptid)));
    if (!empty($ptid)) {
        $template = $pubtypes[$ptid]['name'];
    } else {
        // TODO: allow templates per category ?
        $template = null;
    }
    return xarTplModule('publications', 'user', 'archive', $data, $template);
}
Example #10
0
/**
 * get an array of child categories with links and optional counts
 *
 * @param $args['state'] array of requested status(es) for the publications
 * @param $args['ptid'] publication type ID
 * @param $args['cid'] parent category ID
 * @param $args['showcid'] false (default) means skipping the parent cid
 * @param $args['count'] true (default) means counting the number of publications
 * @param $args['filter'] additional categories we're filtering on (= catid)
 * @return array
 */
function publications_userapi_getchildcats($args)
{
    extract($args);
    if (!isset($cid) || !is_numeric($cid)) {
        return array();
    }
    if (empty($ptid)) {
        $ptid = null;
    }
    if (!isset($state)) {
        // frontpage or approved
        $state = array(PUBLICATIONS_STATE_FRONTPAGE, PUBLICATIONS_STATE_APPROVED);
    }
    if (!isset($showcid)) {
        $showcid = false;
    }
    if (!isset($count)) {
        $count = true;
    }
    if (!isset($filter)) {
        $filter = '';
    }
    if (!xarModAPILoad('categories', 'visual')) {
        return;
    }
    // TODO: make sure permissions are taken into account here !
    $list = xarModAPIFunc('categories', 'visual', 'listarray', array('cid' => $cid));
    // get the counts for all child categories
    if ($count) {
        if (empty($filter)) {
            $seencid = array();
            foreach ($list as $info) {
                $seencid[$info['id']] = 1;
            }
            $childlist = array_keys($seencid);
            $andcids = false;
        } else {
            // we'll combine the parent cid with the filter here
            $childlist = array('_' . $cid, $filter);
            $andcids = true;
        }
        $pubcatcount = xarModAPIFunc('publications', 'user', 'getpubcatcount', array('state' => array(PUBLICATIONS_STATE_FRONTPAGE, PUBLICATIONS_STATE_APPROVED), 'cids' => $childlist, 'andcids' => $andcids, 'ptid' => $ptid, 'reverse' => 1));
        if (!empty($ptid)) {
            $curptid = $ptid;
        } else {
            $curptid = 'total';
        }
    }
    $cats = array();
    foreach ($list as $info) {
        if ($info['id'] == $cid && !$showcid) {
            continue;
        }
        if (!empty($filter)) {
            $catid = $filter . '+' . $info['id'];
        } else {
            $catid = $info['id'];
        }
        // TODO: show icons instead of (or in addition to) a link if available ?
        $info['link'] = xarModURL('publications', 'user', 'view', array('ptid' => $ptid, 'catid' => $catid));
        $info['name'] = xarVarPrepForDisplay($info['name']);
        if ($count) {
            if (isset($pubcatcount[$info['id']][$curptid])) {
                $info['count'] = $pubcatcount[$info['id']][$curptid];
            } elseif (!empty($filter) && isset($pubcatcount[$filter . '+' . $info['id']][$curptid])) {
                $info['count'] = $pubcatcount[$filter . '+' . $info['id']][$curptid];
            } elseif (!empty($filter) && isset($pubcatcount[$info['id'] . '+' . $filter][$curptid])) {
                $info['count'] = $pubcatcount[$info['id'] . '+' . $filter][$curptid];
            } else {
                $info['count'] = '';
            }
        } else {
            $info['count'] = '';
        }
        $cats[] = $info;
    }
    return $cats;
}
Example #11
0
/**
 * get a list of article authors depending on additional module criteria
 *
 * @param $args['cids'] array of cids that we are counting for (OR/AND)
 * @param $args['andcids'] true means AND-ing categories listed in cids
 *
 * @param $args['owner'] the ID of the author
 * @param $args['ptid'] publication type ID (for news, sections, reviews, ...)
 * @param $args['state'] array of requested status(es) for the publications
 * @param $args['startdate'] publications published at startdate or later
 *                           (unix timestamp format)
 * @param $args['enddate'] publications published before enddate
 *                         (unix timestamp format)
 * @return array of author id => author name
 */
function publications_userapi_getauthors($args)
{
    // Database information
    $dbconn = xarDB::getConn();
    // Get the field names and LEFT JOIN ... ON ... parts from publications
    // By passing on the $args, we can let leftjoin() create the WHERE for
    // the publications-specific columns too now
    $publicationsdef = xarModAPIFunc('publications', 'user', 'leftjoin', $args);
    // Load API
    if (!xarModAPILoad('roles', 'user')) {
        return;
    }
    // Get the field names and LEFT JOIN ... ON ... parts from users
    $usersdef = xarModAPIFunc('roles', 'user', 'leftjoin');
    // TODO: make sure this is SQL standard
    // Start building the query
    $query = 'SELECT DISTINCT ' . $publicationsdef['owner'] . ', ' . $usersdef['name'];
    $query .= ' FROM ' . $publicationsdef['table'];
    // Add the LEFT JOIN ... ON ... parts from users
    $query .= ' LEFT JOIN ' . $usersdef['table'];
    $query .= ' ON ' . $usersdef['field'] . ' = ' . $publicationsdef['owner'];
    if (!isset($args['cids'])) {
        $args['cids'] = array();
    }
    if (!isset($args['andcids'])) {
        $args['andcids'] = false;
    }
    if (count($args['cids']) > 0) {
        // Load API
        if (!xarModAPILoad('categories', 'user')) {
            return;
        }
        // Get the LEFT JOIN ... ON ...  and WHERE (!) parts from categories
        $args['modid'] = xarModGetIDFromName('publications');
        if (isset($args['ptid']) && !isset($args['itemtype'])) {
            $args['itemtype'] = $args['ptid'];
        }
        $categoriesdef = xarModAPIFunc('categories', 'user', 'leftjoin', $args);
        $query .= ' LEFT JOIN ' . $categoriesdef['table'];
        $query .= ' ON ' . $categoriesdef['field'] . ' = ' . $publicationsdef['id'];
        $query .= $categoriesdef['more'];
        $docid = 1;
    }
    // Create the WHERE part
    $where = array();
    // we rely on leftjoin() to create the necessary publications clauses now
    if (!empty($publicationsdef['where'])) {
        $where[] = $publicationsdef['where'];
    }
    if (!empty($docid)) {
        // we rely on leftjoin() to create the necessary categories clauses
        $where[] = $categoriesdef['where'];
    }
    if (count($where) > 0) {
        $query .= ' WHERE ' . join(' AND ', $where);
    }
    // Order by author name
    $query .= ' ORDER BY ' . $usersdef['name'] . ' ASC';
    // Run the query - finally :-)
    $result =& $dbconn->Execute($query);
    if (!$result) {
        return;
    }
    $authors = array();
    while (!$result->EOF) {
        list($uid, $name) = $result->fields;
        $authors[$uid] = array('id' => $uid, 'name' => $name);
        $result->MoveNext();
    }
    $result->Close();
    return $authors;
}
Example #12
0
/**
 * Update a publication type
 *
 * @param id $args['ptid'] ID of the publication type
 * @param string $args['name'] name of the publication type (not allowed here)
 * @param string $args['description'] description of the publication type
 * @param array $args['config'] configuration of the publication type
 * @return bool true on success, false on failure
 */
function publications_adminapi_updatepubtype($args)
{
    // Get arguments from argument array
    extract($args);
    // Argument check - make sure that all required arguments are present
    // and in the right format, if not then set an appropriate error
    // message and return
    // Note : since we have several arguments we want to check here, we'll
    // report all those that are invalid at the same time...
    $invalid = array();
    if (!isset($ptid) || !is_numeric($ptid) || $ptid < 1) {
        $invalid[] = 'publication type ID';
    }
    /*
        if (!isset($name) || !is_string($name) || empty($name)) {
            $invalid[] = 'name';
        }
    */
    if (!isset($descr) || !is_string($descr) || empty($descr)) {
        $invalid[] = 'description';
    }
    if (!isset($config) || !is_array($config) || count($config) == 0) {
        $invalid[] = 'configuration';
    }
    if (count($invalid) > 0) {
        $msg = xarML('Invalid #(1) for #(2) function #(3)() in module #(4)', join(', ', $invalid), 'admin', 'updatepubtype', 'Publications');
        throw new BadParameterException(null, $msg);
    }
    // Security check - we require ADMIN rights here
    if (!xarSecurityCheck('AdminPublications', 1, 'Publication', "{$ptid}:All:All:All")) {
        return;
    }
    // Load user API to obtain item information function
    if (!xarModAPILoad('publications', 'user')) {
        return;
    }
    // Get current publication types
    $pubtypes = xarModAPIFunc('publications', 'user', 'get_pubtypes');
    if (!isset($pubtypes[$ptid])) {
        $msg = xarML('Invalid #(1) for #(2) function #(3)() in module #(4)', 'publication type ID', 'admin', 'updatepubtype', 'Publications');
        throw new BadParameterException(null, $msg);
    }
    // Make sure we have all the configuration fields we need
    $pubfields = xarModAPIFunc('publications', 'user', 'getpubfields');
    foreach ($pubfields as $field => $value) {
        if (!isset($config[$field])) {
            $config[$field] = '';
        }
    }
    // Get database setup
    $dbconn = xarDB::getConn();
    $xartable = xarDB::getTables();
    $pubtypestable = $xartable['publication_types'];
    // Update the publication type (don't allow updates on name)
    $query = "UPDATE {$pubtypestable}\n            SET pubtypedescr = ?,\n                pubtypeconfig = ?\n            WHERE pubtype_id = ?";
    $bindvars = array($descr, serialize($config), $ptid);
    $result =& $dbconn->Execute($query, $bindvars);
    if (!$result) {
        return;
    }
    return true;
}
Example #13
0
/**
 * get overview of all publications
 * Note : the following parameters are all optional
 *
 * @param $args['numitems'] number of publications to get
 * @param $args['sort'] sort order ('create_date','title','hits','rating','author','id','summary','notes',...)
 * @param $args['startnum'] starting article number
 * @param $args['ids'] array of article ids to get
 * @param $args['owner'] the ID of the author
 * @param $args['ptid'] publication type ID (for news, sections, reviews, ...)
 * @param $args['state'] array of requested status(es) for the publications
 * @param $args['search'] search parameter(s)
 * @param $args['searchfields'] array of fields to search in
 * @param $args['searchtype'] start, end, like, eq, gt, ... (TODO)
 * @param $args['cids'] array of category IDs for which to get publications (OR/AND)
 *                      (for all categories don?t set it)
 * @param $args['andcids'] true means AND-ing categories listed in cids
 * @param $args['create_date'] publications published in a certain year (YYYY), month (YYYY-MM) or day (YYYY-MM-DD)
 * @param $args['startdate'] publications published at startdate or later
 *                           (unix timestamp format)
 * @param $args['enddate'] publications published before enddate
 *                         (unix timestamp format)
 * @param $args['fields'] array with all the fields to return per publication
 *                        Default list is : 'id','title','summary','owner',
 *                        'create_date','pubtype_id','notes','state','body1'
 *                        Optional fields : 'cids','author','counter','rating','dynamicdata'
 * @param $args['extra'] array with extra fields to return per article (in addition
 *                       to the default list). So you can EITHER specify *all* the
 *                       fields you want with 'fields', OR take all the default
 *                       ones and add some optional fields with 'extra'
 * @param $args['where'] additional where clauses (e.g. myfield gt 1234)
 * @param $args['locale'] language/locale (if not using multi-sites, categories etc.)
 * @return array Array of publications, or false on failure
 */
function publications_userapi_getall($args)
{
    // Get arguments from argument array
    extract($args);
    // Optional argument
    if (!isset($startnum)) {
        $startnum = 1;
    }
    if (empty($cids)) {
        $cids = array();
    }
    if (!isset($andcids)) {
        $andcids = false;
    }
    if (empty($ptid)) {
        $ptid = null;
    }
    // Default fields in publications (for now)
    $columns = array('id', 'name', 'title', 'description', 'summary', 'body1', 'owner', 'pubtype_id', 'notes', 'state', 'start_date');
    // Optional fields in publications (for now)
    // + 'cids' = list of categories an article belongs to
    // + 'author' = user name of owner
    // + 'counter' = number of times this article was displayed (hitcount)
    // + 'rating' = rating for this article (ratings)
    // + 'dynamicdata' = dynamic data fields for this article (dynamicdata)
    // + 'relevance' = relevance for this article (MySQL full-text search only)
    // $optional = array('cids','author','counter','rating','dynamicdata','relevance');
    if (!isset($fields)) {
        $fields = $columns;
    }
    if (isset($extra) && is_array($extra) && count($extra) > 0) {
        $fields = array_merge($fields, $extra);
    }
    if (empty($sort)) {
        if (!empty($search) && !empty($searchtype) && substr($searchtype, 0, 8) == 'fulltext') {
            if ($searchtype == 'fulltext boolean' && !in_array('relevance', $fields)) {
                // add the relevance to the field list for sorting
                $fields[] = 'relevance';
            }
            // let the database sort by relevance (= default for fulltext)
            $sortlist = array();
        } else {
            // default sort by create_date
            $sortlist = array('create_date');
        }
    } elseif (is_array($sort)) {
        $sortlist = $sort;
    } else {
        $sortlist = explode(',', $sort);
    }
    $publications = array();
    // Security check
    if (!xarSecurityCheck('ViewPublications')) {
        return;
    }
    // Fields requested by the calling function
    $required = array();
    foreach ($fields as $field) {
        $required[$field] = 1;
    }
    // mandatory fields for security
    $required['id'] = 1;
    $required['title'] = 1;
    $required['pubtype_id'] = 1;
    $required['create_date'] = 1;
    $required['owner'] = 1;
    // not to be confused with author (name) :-)
    // force cids as required when categories are given
    if (count($cids) > 0) {
        $required['cids'] = 1;
    }
    // TODO: put all this in dynamic data and retrieve everything via there (including hooked stuff)
    // Database information
    $dbconn = xarDB::getConn();
    // Get the field names and LEFT JOIN ... ON ... parts from publications
    // By passing on the $args, we can let leftjoin() create the WHERE for
    // the publications-specific columns too now
    $publicationsdef = xarModAPIFunc('publications', 'user', 'leftjoin', $args);
    // TODO : how to handle the case where name is empty, but uname isn't
    if (!empty($required['owner'])) {
        // Load API
        if (!xarModAPILoad('roles', 'user')) {
            return;
        }
        // Get the field names and LEFT JOIN ... ON ... parts from users
        $usersdef = xarModAPIFunc('roles', 'user', 'leftjoin');
        if (empty($usersdef)) {
            return;
        }
    }
    $regid = xarMod::getRegID('publications');
    if (!empty($required['cids'])) {
        // Load API
        if (!xarModAPILoad('categories', 'user')) {
            return;
        }
        // Get the LEFT JOIN ... ON ...  and WHERE (!) parts from categories
        $categoriesdef = xarModAPIFunc('categories', 'user', 'leftjoin', array('cids' => $cids, 'andcids' => $andcids, 'itemtype' => isset($ptid) ? $ptid : null, 'modid' => $regid));
        if (empty($categoriesdef)) {
            return;
        }
    }
    if (!empty($required['counter']) && xarModIsHooked('hitcount', 'publications', $ptid)) {
        // Load API
        if (!xarModAPILoad('hitcount', 'user')) {
            return;
        }
        // Get the LEFT JOIN ... ON ...  and WHERE (!) parts from hitcount
        $hitcountdef = xarModAPIFunc('hitcount', 'user', 'leftjoin', array('modid' => $regid, 'itemtype' => isset($ptid) ? $ptid : null));
    }
    if (!empty($required['rating']) && xarModIsHooked('ratings', 'publications', $ptid)) {
        // Load API
        if (!xarModAPILoad('ratings', 'user')) {
            return;
        }
        // Get the LEFT JOIN ... ON ...  and WHERE (!) parts from ratings
        $ratingsdef = xarModAPIFunc('ratings', 'user', 'leftjoin', array('modid' => $regid, 'itemtype' => isset($ptid) ? $ptid : null));
    }
    // Create the SELECT part
    $select = array();
    foreach ($required as $field => $val) {
        // we'll handle this later
        if ($field == 'cids') {
            continue;
        } elseif ($field == 'dynamicdata') {
            continue;
        } elseif ($field == 'owner') {
            $select[] = $usersdef['name'];
        } elseif ($field == 'counter') {
            if (!empty($hitcountdef['hits'])) {
                $select[] = $hitcountdef['hits'];
            }
        } elseif ($field == 'rating') {
            if (!empty($ratingsdef['rating'])) {
                $select[] = $ratingsdef['rating'];
            }
        } else {
            $select[] = $publicationsdef[$field];
        }
    }
    // FIXME: <rabbitt> PostgreSQL requires that all fields in an 'Order By' be in the SELECT
    //        this has been added to remove the error that not having it creates
    // FIXME: <mikespub> Oracle doesn't allow having the same field in a query twice if you
    //        don't specify an alias (at least in sub-queries, which is what SelectLimit uses)
    //    if (!in_array($publicationsdef['create_date'], $select)) {
    //        $select[] = $publicationsdef['create_date'];
    //    }
    // we need distinct for multi-category OR selects where publications fit in more than 1 category
    if (count($cids) > 0) {
        $query = 'SELECT DISTINCT ' . join(', ', $select);
    } else {
        $query = 'SELECT ' . join(', ', $select);
    }
    // Create the FROM ... [LEFT JOIN ... ON ...] part
    $from = $publicationsdef['table'];
    $addme = 0;
    if (!empty($required['owner'])) {
        // Add the LEFT JOIN ... ON ... parts from users
        $from .= ' LEFT JOIN ' . $usersdef['table'];
        $from .= ' ON ' . $usersdef['field'] . ' = ' . $publicationsdef['owner'];
        $addme = 1;
    }
    if (!empty($required['counter']) && isset($hitcountdef)) {
        // add this for SQL compliance when there are multiple JOINs
        // bug 4429: sqlite doesnt like the parentheses
        if ($addme && $dbconn->databaseType != 'sqlite') {
            $from = '(' . $from . ')';
        }
        // Add the LEFT JOIN ... ON ... parts from hitcount
        $from .= ' LEFT JOIN ' . $hitcountdef['table'];
        $from .= ' ON ' . $hitcountdef['field'] . ' = ' . $publicationsdef['id'];
        $addme = 1;
    }
    if (!empty($required['rating']) && isset($ratingsdef)) {
        // add this for SQL compliance when there are multiple JOINs
        // bug 4429: sqlite doesnt like the parentheses
        if ($addme && $dbconn->databaseType != 'sqlite') {
            $from = '(' . $from . ')';
        }
        // Add the LEFT JOIN ... ON ... parts from ratings
        $from .= ' LEFT JOIN ' . $ratingsdef['table'];
        $from .= ' ON ' . $ratingsdef['field'] . ' = ' . $publicationsdef['id'];
        $addme = 1;
    }
    if (count($cids) > 0) {
        // add this for SQL compliance when there are multiple JOINs
        // bug 4429: sqlite doesnt like the parentheses
        if ($addme && $dbconn->databaseType != 'sqlite') {
            $from = '(' . $from . ')';
        }
        // Add the LEFT JOIN ... ON ... parts from categories
        $from .= ' LEFT JOIN ' . $categoriesdef['table'];
        $from .= ' ON ' . $categoriesdef['field'] . ' = ' . $publicationsdef['id'];
        if (!empty($categoriesdef['more']) && $dbconn->databaseType != 'sqlite') {
            $from = '(' . $from . ')';
            $from .= $categoriesdef['more'];
        }
    }
    $query .= ' FROM ' . $from;
    // TODO: check the order of the conditions for brain-dead databases ?
    // Create the WHERE part
    $where = array();
    // we rely on leftjoin() to create the necessary publications clauses now
    if (!empty($publicationsdef['where'])) {
        $where[] = $publicationsdef['where'];
    }
    if (!empty($required['counter']) && !empty($hitcountdef['where'])) {
        $where[] = $hitcountdef['where'];
    }
    if (!empty($required['rating']) && !empty($ratingsdef['where'])) {
        $where[] = $ratingsdef['where'];
    }
    if (count($cids) > 0) {
        // we rely on leftjoin() to create the necessary categories clauses
        $where[] = $categoriesdef['where'];
    }
    if (count($where) > 0) {
        $query .= ' WHERE ' . join(' AND ', $where);
    }
    // TODO: support other non-publications fields too someday ?
    // Create the ORDER BY part
    if (count($sortlist) > 0) {
        $sortparts = array();
        $seenid = 0;
        foreach ($sortlist as $criteria) {
            // ignore empty sort criteria
            if (empty($criteria)) {
                continue;
            }
            // split off trailing ASC or DESC
            if (preg_match('/^(.+)\\s+(ASC|DESC)\\s*$/i', $criteria, $matches)) {
                $criteria = trim($matches[1]);
                $sortorder = strtoupper($matches[2]);
            } else {
                $sortorder = '';
            }
            if ($criteria == 'title') {
                $sortparts[] = $publicationsdef['title'] . ' ' . (!empty($sortorder) ? $sortorder : 'ASC');
                //            } elseif ($criteria == 'create_date' || $criteria == 'date') {
                //                $sortparts[] = $publicationsdef['create_date'] . ' ' . (!empty($sortorder) ? $sortorder : 'DESC');
            } elseif ($criteria == 'hits' && !empty($hitcountdef['hits'])) {
                $sortparts[] = $hitcountdef['hits'] . ' ' . (!empty($sortorder) ? $sortorder : 'DESC');
            } elseif ($criteria == 'rating' && !empty($ratingsdef['rating'])) {
                $sortparts[] = $ratingsdef['rating'] . ' ' . (!empty($sortorder) ? $sortorder : 'DESC');
            } elseif ($criteria == 'owner' && !empty($usersdef['name'])) {
                $sortparts[] = $usersdef['name'] . ' ' . (!empty($sortorder) ? $sortorder : 'ASC');
            } elseif ($criteria == 'relevance' && !empty($publicationsdef['relevance'])) {
                $sortparts[] = 'relevance' . ' ' . (!empty($sortorder) ? $sortorder : 'DESC');
            } elseif ($criteria == 'id') {
                $sortparts[] = $publicationsdef['id'] . ' ' . (!empty($sortorder) ? $sortorder : 'ASC');
                $seenid = 1;
                // other publications fields, e.g. summary, notes, ...
            } elseif (!empty($publicationsdef[$criteria])) {
                $sortparts[] = $publicationsdef[$criteria] . ' ' . (!empty($sortorder) ? $sortorder : 'ASC');
            } else {
                // ignore unknown sort fields
            }
        }
        // add sorting by id for unique sort order
        if (count($sortparts) < 2 && empty($seenid)) {
            $sortparts[] = $publicationsdef['id'] . ' DESC';
        }
        $query .= ' ORDER BY ' . join(', ', $sortparts);
    } elseif (!empty($search) && !empty($searchtype) && substr($searchtype, 0, 8) == 'fulltext') {
        // For fulltext, let the database return the publications by relevance here (= default)
        // For fulltext in boolean mode, add MATCH () ... AS relevance ... ORDER BY relevance DESC (cfr. leftjoin)
        if (!empty($required['relevance']) && $searchtype == 'fulltext boolean') {
            $query .= ' ORDER BY relevance DESC, ' . $publicationsdef['create_date'] . ' DESC, ' . $publicationsdef['id'] . ' DESC';
        }
    } else {
        // default is 'create_date'
        $query .= ' ORDER BY ' . $publicationsdef['create_date'] . ' DESC, ' . $publicationsdef['id'] . ' DESC';
    }
    //echo $query;
    // Run the query - finally :-)
    if (isset($numitems) && is_numeric($numitems)) {
        $result =& $dbconn->SelectLimit($query, $numitems, $startnum - 1);
    } else {
        $result =& $dbconn->Execute($query);
    }
    if (!$result) {
        return;
    }
    $itemids_per_type = array();
    // Put publications into result array
    for (; !$result->EOF; $result->MoveNext()) {
        $data = $result->fields;
        $item = array();
        // loop over all required fields again
        foreach ($required as $field => $val) {
            if ($field == 'cids' || $field == 'dynamicdata' || $val != 1) {
                continue;
            }
            $value = array_shift($data);
            if ($field == 'rating') {
                $value = intval($value);
            }
            $item[$field] = $value;
        }
        // check security - don't generate an exception here
        if (empty($required['cids']) && !xarSecurityCheck('ViewPublications', 0, 'Publication', "{$item['pubtype_id']}:All:{$item['owner']}:{$item['id']}")) {
            continue;
        }
        $publications[] = $item;
        if (!empty($required['dynamicdata'])) {
            $pubtype = $item['pubtype_id'];
            if (!isset($itemids_per_type[$pubtype])) {
                $itemids_per_type[$pubtype] = array();
            }
            $itemids_per_type[$pubtype][] = $item['id'];
        }
    }
    $result->Close();
    if (!empty($required['cids']) && count($publications) > 0) {
        // Get all the categories at once
        $ids = array();
        foreach ($publications as $article) {
            $ids[] = $article['id'];
        }
        // Load API
        if (!xarModAPILoad('categories', 'user')) {
            return;
        }
        // Get the links for the Array of iids we have
        $cids = xarModAPIFunc('categories', 'user', 'getlinks', array('iids' => $ids, 'reverse' => 1, 'modid' => $regid));
        // Inserting the corresponding Category ID in the Publication Description
        $delete = array();
        $cachesec = array();
        foreach ($publications as $key => $article) {
            if (isset($cids[$article['id']]) && count($cids[$article['id']]) > 0) {
                $publications[$key]['cids'] = $cids[$article['id']];
                foreach ($cids[$article['id']] as $cid) {
                    if (!xarSecurityCheck('ViewPublications', 0, 'Publication', "{$article['pubtype_id']}:{$cid}:{$article['owner']}:{$article['id']}")) {
                        $delete[$key] = 1;
                        break;
                    }
                    if (!isset($cachesec[$cid])) {
                        // TODO: combine with ViewCategoryLink check when we can combine module-specific
                        // security checks with "parent" security checks transparently ?
                        $cachesec[$cid] = xarSecurityCheck('ReadCategories', 0, 'Category', "All:{$cid}");
                    }
                    if (!$cachesec[$cid]) {
                        $delete[$key] = 1;
                        break;
                    }
                }
            } else {
                if (!xarSecurityCheck('ViewPublications', 0, 'Publication', "{$article['pubtype_id']}:All:{$article['owner']}:{$article['id']}")) {
                    $delete[$key] = 1;
                    continue;
                }
            }
        }
        if (count($delete) > 0) {
            foreach ($delete as $key => $val) {
                unset($publications[$key]);
            }
        }
    }
    if (!empty($required['dynamicdata']) && count($publications) > 0) {
        foreach ($itemids_per_type as $pubtype => $itemids) {
            if (!xarModIsHooked('dynamicdata', 'publications', $pubtype)) {
                continue;
            }
            list($properties, $items) = xarModAPIFunc('dynamicdata', 'user', 'getitemsforview', array('module' => 'publications', 'itemtype' => $pubtype, 'itemids' => $itemids, 'state' => 1));
            if (empty($properties) || count($properties) == 0) {
                continue;
            }
            foreach ($publications as $key => $article) {
                // otherwise publications (of different pub types) with dd properties having the same
                // names reset previously set values to empty string for each iteration based on the pubtype
                if ($article['pubtype_id'] != $pubtype) {
                    continue;
                }
                foreach (array_keys($properties) as $name) {
                    if (isset($items[$article['id']]) && isset($items[$article['id']][$name])) {
                        $value = $items[$article['id']][$name];
                    } else {
                        $value = $properties[$name]->default;
                    }
                    $publications[$key][$name] = $value;
                    // TODO: clean up this temporary fix
                    if (!empty($value)) {
                        $publications[$key][$name . '_output'] = $properties[$name]->showOutput(array('value' => $value));
                    }
                }
            }
        }
    }
    return $publications;
}