Piwik\Plugins\Live\Model::makeLogVisitsQueryString PHP Method

makeLogVisitsQueryString() public method

public makeLogVisitsQueryString ( $idSite, $period, $date, $segment, integer $offset, integer $limit, $visitorId, $minTimestamp, $filterSortOrder ) : array
$idSite
$period
$date
$segment
$offset integer
$limit integer
$visitorId
$minTimestamp
$filterSortOrder
return array
    public function makeLogVisitsQueryString($idSite, $period, $date, $segment, $offset, $limit, $visitorId, $minTimestamp, $filterSortOrder)
    {
        // If no other filter, only look at the last 24 hours of stats
        if (empty($visitorId) && empty($limit) && empty($offset) && empty($period) && empty($date)) {
            $period = 'day';
            $date = 'yesterdaySameTime';
        }
        list($whereClause, $bindIdSites) = $this->getIdSitesWhereClause($idSite);
        list($whereBind, $where) = $this->getWhereClauseAndBind($whereClause, $bindIdSites, $idSite, $period, $date, $visitorId, $minTimestamp);
        if (strtolower($filterSortOrder) !== 'asc') {
            $filterSortOrder = 'DESC';
        }
        $segment = new Segment($segment, $idSite);
        // Subquery to use the indexes for ORDER BY
        $select = "log_visit.*";
        $from = "log_visit";
        $groupBy = false;
        $limit = $limit >= 1 ? (int) $limit : 0;
        $offset = $offset >= 1 ? (int) $offset : 0;
        $orderBy = '';
        if (count($bindIdSites) <= 1) {
            $orderBy = 'idsite ' . $filterSortOrder . ', ';
        }
        $orderBy .= "visit_last_action_time " . $filterSortOrder;
        $orderByParent = "sub.visit_last_action_time " . $filterSortOrder;
        // this $innerLimit is a workaround (see https://github.com/piwik/piwik/issues/9200#issuecomment-183641293)
        $innerLimit = $limit;
        if (!$segment->isEmpty()) {
            $innerLimit = $limit * 10;
        }
        $innerQuery = $segment->getSelectQuery($select, $from, $where, $whereBind, $orderBy, $groupBy, $innerLimit, $offset);
        $bind = $innerQuery['bind'];
        // Group by idvisit so that a given visit appears only once, useful when for example:
        // 1) when a visitor converts 2 goals
        // 2) when an Action Segment is used, the inner query will return one row per action, but we want one row per visit
        $sql = "\n\t\t\tSELECT sub.* FROM (\n\t\t\t\t" . $innerQuery['sql'] . "\n\t\t\t) AS sub\n\t\t\tGROUP BY sub.idvisit\n\t\t\tORDER BY {$orderByParent}\n\t\t";
        if ($limit) {
            $sql .= sprintf("LIMIT %d \n", $limit);
        }
        return array($sql, $bind);
    }

Usage Example

Example #1
0
    public function test_makeLogVisitsQueryString_whenSegment()
    {
        $model = new Model();
        list($sql, $bind) = $model->makeLogVisitsQueryString($idSite = 1, $period = 'month', $date = '2010-01-01', $segment = 'customVariablePageName1==Test', $offset = 0, $limit = 100, $visitorId = 'abc', $minTimestamp = false, $filterSortOrder = false);
        $expectedSql = ' SELECT sub.* FROM
                (

                    SELECT log_inner.*
                    FROM (
                        SELECT log_visit.*
                        FROM ' . Common::prefixTable('log_visit') . ' AS log_visit
                          LEFT JOIN ' . Common::prefixTable('log_link_visit_action') . ' AS log_link_visit_action
                          ON log_link_visit_action.idvisit = log_visit.idvisit
                        WHERE ( log_visit.idsite in (?)
                          AND log_visit.idvisitor = ?
                          AND log_visit.visit_last_action_time >= ?
                          AND log_visit.visit_last_action_time <= ? )
                          AND ( log_link_visit_action.custom_var_k1 = ? )
                        ORDER BY idsite, visit_last_action_time DESC
                        LIMIT 100
                        ) AS log_inner
                    ORDER BY idsite, visit_last_action_time DESC
                    LIMIT 100
                 ) AS sub
                 GROUP BY sub.idvisit
                 ORDER BY sub.visit_last_action_time DESC
        ';
        $expectedBind = array('1', Common::hex2bin('abc'), '2010-01-01 00:00:00', '2010-02-01 00:00:00', 'Test');
        $this->assertEquals(SegmentTest::removeExtraWhiteSpaces($expectedSql), SegmentTest::removeExtraWhiteSpaces($sql));
        $this->assertEquals(SegmentTest::removeExtraWhiteSpaces($expectedBind), SegmentTest::removeExtraWhiteSpaces($bind));
    }