ArticleSearch::getSparseArray PHP Method

getSparseArray() public method

See SubmissionSearch::getSparseArray()
public getSparseArray ( &$unorderedResults, $orderBy, $orderDir, $exclude )
    function &getSparseArray(&$unorderedResults, $orderBy, $orderDir, $exclude)
    {
        // Calculate a well-ordered (unique) score.
        $resultCount = count($unorderedResults);
        $i = 0;
        foreach ($unorderedResults as $submissionId => &$data) {
            $data['score'] = $resultCount * $data['count'] + $i++;
            unset($data);
        }
        // If we got a primary sort order then apply it and use score as secondary
        // order only.
        // NB: We apply order after merging and before paging/formatting. Applying
        // order before merging (i.e. in ArticleSearchDAO) would require us to
        // retrieve dependent objects for results being purged later. Doing
        // everything in a closed SQL is not possible (e.g. for authors). Applying
        // sort order after paging and formatting is not possible as we have to
        // order the whole list before slicing it. So this seems to be the most
        // appropriate place, although we may have to retrieve some objects again
        // when formatting results.
        $orderedResults = array();
        $authorDao = DAORegistry::getDAO('AuthorDAO');
        /* @var $authorDao AuthorDAO */
        $articleDao = DAORegistry::getDAO('ArticleDAO');
        /* @var $articleDao ArticleDAO */
        $journalDao = DAORegistry::getDAO('JournalDAO');
        /* @var $journalDao JournalDAO */
        $journalTitles = array();
        if ($orderBy == 'popularityAll' || $orderBy == 'popularityMonth') {
            $application = PKPApplication::getApplication();
            $metricType = $application->getDefaultMetricType();
            if (is_null($metricType)) {
                // If no default metric has been found then sort by score...
                $orderBy = 'score';
            } else {
                // Retrieve a metrics report for all articles.
                $column = STATISTICS_DIMENSION_ARTICLE_ID;
                $filter = array(STATISTICS_DIMENSION_ASSOC_TYPE => array(ASSOC_TYPE_GALLEY, ASSOC_TYPE_ARTICLE), STATISTICS_DIMENSION_ARTICLE_ID => array(array_keys($unorderedResults)));
                if ($orderBy == 'popularityMonth') {
                    $oneMonthAgo = date('Ymd', strtotime('-1 month'));
                    $today = date('Ymd');
                    $filter[STATISTICS_DIMENSION_DAY] = array('from' => $oneMonthAgo, 'to' => $today);
                }
                $rawReport = $application->getMetrics($metricType, $column, $filter);
                foreach ($rawReport as $row) {
                    $unorderedResults[$row['submission_id']]['metric'] = (int) $row['metric'];
                }
            }
        }
        $i = 0;
        // Used to prevent ties from clobbering each other
        foreach ($unorderedResults as $submissionId => $data) {
            // Exclude unwanted IDs.
            if (in_array($submissionId, $exclude)) {
                continue;
            }
            switch ($orderBy) {
                case 'authors':
                    $authors = $authorDao->getBySubmissionId($submissionId);
                    $authorNames = array();
                    foreach ($authors as $author) {
                        /* @var $author Author */
                        $authorNames[] = $author->getFullName(true);
                    }
                    $orderKey = implode('; ', $authorNames);
                    unset($authors, $authorNames);
                    break;
                case 'title':
                    $submission = $articleDao->getById($submissionId);
                    $orderKey = $submission->getLocalizedTitle(null, false);
                    break;
                case 'journalTitle':
                    if (!isset($journalTitles[$data['journal_id']])) {
                        $journal = $journalDao->getById($data['journal_id']);
                        $journalTitles[$data['journal_id']] = $journal->getLocalizedName();
                    }
                    $orderKey = $journalTitles[$data['journal_id']];
                    break;
                case 'issuePublicationDate':
                case 'publicationDate':
                    $orderKey = $data[$orderBy];
                    break;
                case 'popularityAll':
                case 'popularityMonth':
                    $orderKey = isset($data['metric']) ? $data['metric'] : 0;
                    break;
                default:
                    // order by score.
                    $orderKey = $data['score'];
            }
            if (!isset($orderedResults[$orderKey])) {
                $orderedResults[$orderKey] = array();
            }
            $orderedResults[$orderKey][$data['score'] + $i++] = $submissionId;
        }
        // Order the results by primary order.
        if (strtolower($orderDir) == 'asc') {
            ksort($orderedResults);
        } else {
            krsort($orderedResults);
        }
        // Order the result by secondary order and flatten it.
        $finalOrder = array();
        foreach ($orderedResults as $orderKey => $submissionIds) {
            if (count($submissionIds) == 1) {
                $finalOrder[] = array_pop($submissionIds);
            } else {
                if (strtolower($orderDir) == 'asc') {
                    ksort($submissionIds);
                } else {
                    krsort($submissionIds);
                }
                $finalOrder = array_merge($finalOrder, array_values($submissionIds));
            }
        }
        return $finalOrder;
    }