public function setOrder($field, $desc = null)
    {
        // fields passed as CSV string
        if (is_string($field) && strpos($field, ',') !== false) {
            $field = explode(',', $field);
        }

        // fields passed as array
        if (is_array($field)) {
            if (null !== $desc) {
                throw new Exception([
                    'If first argument is array, second argument must not be used',
                    'arg1' => $field,
                    'arg2' => $desc,
                ]);
            }

            foreach (array_reverse($field) as $key=>$o) {
                if (is_int($key)) {
                    if (is_array($o)) {
                        // format [field,order]
                        $this->setOrder(...$o);
                    } else {
                        // format "field order"
                        $this->setOrder($o);
                    }
                } else {
                    // format "field"=>order
                    $this->setOrder($key, $o);
                }
            }

            return $this;
        }

        // extract sort order from field name string
        if (null === $desc && is_string($field)) {
            // no realistic workaround in PHP for 2nd argument being null
            $field = trim($field);
            if (strpos($field, ' ') !== false) {
                list($field, $desc) = array_map('trim', explode(' ', $field, 2));
            }
        }

        // finally set order
        $this->order[] = [$field, $desc];

        return $this;
    }