示例#1
0
/**
 * Set subscription information
 *
 * Allows to set subscription informations for permanent storage in meta files.
 * Subscriptions consist of a target object, a subscribing user, a subscribe
 * style and optional data.
 * A subscription may be deleted by specifying an empty subscribe style.
 * Only one subscription per target and user is allowed.
 * The function returns false on error, otherwise true. Note that no error is
 * returned if a subscription should be deleted but the user is not subscribed
 * and the subscription meta file exists.
 *
 * @param string $user      The subscriber or unsubscriber
 * @param string $page      The target object (page or namespace), specified by
 *                          id; Namespaces are identified by a trailing colon.
 * @param string $style     The subscribe style; DokuWiki currently implements
 *                          “every”, “digest”, and “list”.
 * @param string $data      An optional data blob
 * @param bool   $overwrite Whether an existing subscription may be overwritten
 *
 * @author Adrian Lang <*****@*****.**>
 */
function subscription_set($user, $page, $style, $data = null, $overwrite = false)
{
    global $lang;
    if (is_null($style)) {
        // Delete subscription.
        $file = subscription_filename($page);
        if (!@file_exists($file)) {
            msg(sprintf($lang['subscr_not_subscribed'], $user, prettyprint_id($page)), -1);
            return false;
        }
        // io_deleteFromFile does not return false if no line matched.
        return io_deleteFromFile($file, subscription_regex(array('user' => $user)), true);
    }
    // Delete subscription if one exists and $overwrite is true. If $overwrite
    // is false, fail.
    $subs = subscription_find($page, array('user' => $user));
    if (count($subs) > 0 && array_pop(array_keys($subs)) === $page) {
        if (!$overwrite) {
            msg(sprintf($lang['subscr_already_subscribed'], $user, prettyprint_id($page)), -1);
            return false;
        }
        // Fail if deletion failed, else continue.
        if (!subscription_set($user, $page, null)) {
            return false;
        }
    }
    $file = subscription_filename($page);
    $content = auth_nameencode($user) . ' ' . $style;
    if (!is_null($data)) {
        $content .= ' ' . $data;
    }
    return io_saveFile($file, $content . "\n", true);
}
示例#2
0
/**
 * Send digest and list mails for all subscriptions which are in effect for the
 * current page
 *
 * @author Adrian Lang <*****@*****.**>
 */
function sendDigest()
{
    echo 'sendDigest(): started' . NL;
    global $ID;
    global $conf;
    if (!$conf['subscribers']) {
        echo 'sendDigest(): disabled' . NL;
        return false;
    }
    $subscriptions = subscription_find($ID, array('style' => '(digest|list)', 'escaped' => true));
    /** @var auth_basic $auth */
    global $auth;
    global $lang;
    global $conf;
    global $USERINFO;
    // remember current user info
    $olduinfo = $USERINFO;
    $olduser = $_SERVER['REMOTE_USER'];
    foreach ($subscriptions as $id => $users) {
        if (!subscription_lock($id)) {
            continue;
        }
        foreach ($users as $data) {
            list($user, $style, $lastupdate) = $data;
            $lastupdate = (int) $lastupdate;
            if ($lastupdate + $conf['subscribe_time'] > time()) {
                // Less than the configured time period passed since last
                // update.
                continue;
            }
            // Work as the user to make sure ACLs apply correctly
            $USERINFO = $auth->getUserData($user);
            $_SERVER['REMOTE_USER'] = $user;
            if ($USERINFO === false) {
                continue;
            }
            if (substr($id, -1, 1) === ':') {
                // The subscription target is a namespace
                $changes = getRecentsSince($lastupdate, null, getNS($id));
            } else {
                if (auth_quickaclcheck($id) < AUTH_READ) {
                    continue;
                }
                $meta = p_get_metadata($id);
                $changes = array($meta['last_change']);
            }
            // Filter out pages only changed in small and own edits
            $change_ids = array();
            foreach ($changes as $rev) {
                $n = 0;
                while (!is_null($rev) && $rev['date'] >= $lastupdate && ($_SERVER['REMOTE_USER'] === $rev['user'] || $rev['type'] === DOKU_CHANGE_TYPE_MINOR_EDIT)) {
                    $rev = getRevisions($rev['id'], $n++, 1);
                    $rev = count($rev) > 0 ? $rev[0] : null;
                }
                if (!is_null($rev) && $rev['date'] >= $lastupdate) {
                    // Some change was not a minor one and not by myself
                    $change_ids[] = $rev['id'];
                }
            }
            if ($style === 'digest') {
                foreach ($change_ids as $change_id) {
                    subscription_send_digest($USERINFO['mail'], $change_id, $lastupdate);
                }
            } elseif ($style === 'list') {
                subscription_send_list($USERINFO['mail'], $change_ids, $id);
            }
            // TODO: Handle duplicate subscriptions.
            // Update notification time.
            subscription_set($user, $id, $style, time(), true);
        }
        subscription_unlock($id);
    }
    // restore current user info
    $USERINFO = $olduinfo;
    $_SERVER['REMOTE_USER'] = $olduser;
    echo 'sendDigest(): finished' . NL;
    return true;
}
示例#3
0
/**
 * Handle page 'subscribe'
 *
 * Throws exception on error.
 *
 * @author Adrian Lang <*****@*****.**>
 */
function act_subscription($act)
{
    global $lang;
    global $INFO;
    global $ID;
    // get and preprocess data.
    $params = array();
    foreach (array('target', 'style', 'action') as $param) {
        if (isset($_REQUEST["sub_{$param}"])) {
            $params[$param] = $_REQUEST["sub_{$param}"];
        }
    }
    // any action given? if not just return and show the subscription page
    if (!$params['action'] || !checkSecurityToken()) {
        return $act;
    }
    // Handle POST data, may throw exception.
    trigger_event('ACTION_HANDLE_SUBSCRIBE', $params, 'subscription_handle_post');
    $target = $params['target'];
    $style = $params['style'];
    $data = $params['data'];
    $action = $params['action'];
    // Perform action.
    require_once DOKU_INC . 'inc/subscription.php';
    if (!subscription_set($_SERVER['REMOTE_USER'], $target, $style, $data)) {
        throw new Exception(sprintf($lang["subscr_{$action}_error"], hsc($INFO['userinfo']['name']), prettyprint_id($target)));
    }
    msg(sprintf($lang["subscr_{$action}_success"], hsc($INFO['userinfo']['name']), prettyprint_id($target)), 1);
    act_redirect($ID, $act);
    // Assure that we have valid data if act_redirect somehow fails.
    $INFO['subscribed'] = get_info_subscribed();
    return 'show';
}
示例#4
0
/**
 * Send digest and list mails for all subscriptions which are in effect for the
 * current page
 *
 * @author Adrian Lang <*****@*****.**>
 */
function sendDigest()
{
    echo 'sendDigest(): start' . NL;
    global $ID;
    global $conf;
    if (!$conf['subscribers']) {
        return;
    }
    $subscriptions = subscription_find($ID, array('style' => '(digest|list)', 'escaped' => true));
    global $auth;
    global $lang;
    global $conf;
    global $USERINFO;
    // remember current user info
    $olduinfo = $USERINFO;
    $olduser = $_SERVER['REMOTE_USER'];
    foreach ($subscriptions as $id => $users) {
        if (!subscription_lock($id)) {
            continue;
        }
        foreach ($users as $data) {
            list($user, $style, $lastupdate) = $data;
            $lastupdate = (int) $lastupdate;
            if ($lastupdate + $conf['subscribe_time'] > time()) {
                // Less than the configured time period passed since last
                // update.
                continue;
            }
            // Work as the user to make sure ACLs apply correctly
            $USERINFO = $auth->getUserData($user);
            $_SERVER['REMOTE_USER'] = $user;
            if ($USERINFO === false) {
                continue;
            }
            if (substr($id, -1, 1) === ':') {
                // The subscription target is a namespace
                $changes = getRecentsSince($lastupdate, null, getNS($id));
                if (count($changes) === 0) {
                    continue;
                }
                if ($style === 'digest') {
                    foreach ($changes as $change) {
                        subscription_send_digest($USERINFO['mail'], $change, $lastupdate);
                    }
                } elseif ($style === 'list') {
                    subscription_send_list($USERINFO['mail'], $changes, $id);
                }
                // TODO: Handle duplicate subscriptions.
            } else {
                if (auth_quickaclcheck($id) < AUTH_READ) {
                    continue;
                }
                $meta = p_get_metadata($id);
                $rev = $meta['last_change']['date'];
                if ($rev < $lastupdate) {
                    // There is no new revision.
                    continue;
                }
                subscription_send_digest($USERINFO['mail'], $meta['last_change'], $lastupdate);
            }
            // Update notification time.
            subscription_set($user, $id, $style, time(), true);
        }
        subscription_unlock($id);
    }
    // restore current user info
    $USERINFO = $olduinfo;
    $_SERVER['REMOTE_USER'] = $olduser;
}