Пример #1
0
function Streams_0_8_6_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    // access for managing communities
    $access = new Streams_Access();
    $access->publisherId = $app;
    $access->streamName = 'Streams/community*';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
    // access for managing categories
    $access = new Streams_Access();
    $access->publisherId = $app;
    $access->streamName = 'Streams/category/';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['close'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
    // template to help users relate things to Streams/category streams
    Streams_Stream::insert(array('publisherId' => '', 'name' => 'Streams/category/', 'type' => 'Streams/template', 'title' => 'Untitled Category', 'icon' => 'Streams/category', 'content' => '', 'attributes' => null, 'readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['relate'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']))->execute();
    // template to help users create subcategories for things
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/category/', 'type' => 'subcategories', 'fromPublisherId' => '', 'fromStreamName' => 'Streams/category/'))->execute();
}
function Streams_0_8_4_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    $communityId = Users::communityId();
    $user = Users_User::fetch($communityId);
    // avatar for the App user
    $avatar = new Streams_Avatar();
    $avatar->toUserId = $communityId;
    $avatar->publisherId = $communityId;
    $avatar->username = $user->username;
    $avatar->firstName = Users::communityName();
    $avatar->lastName = Users::communitySuffix();
    $avatar->icon = $user->icon;
    $avatar->save();
    $avatar2 = new Streams_Avatar();
    $avatar2->copyFrom($avatar, null, false, true);
    $avatar->toUserId = '';
    $avatar->save();
    // access stream for managing app roles
    $stream = new Streams_Stream();
    $stream->publisherId = Users::communityId();
    $stream->name = 'Streams/contacts';
    $stream->type = 'Streams/resource';
    $stream->title = "Contacts";
    $stream->setAttribute('prefixes', array("Users/", "{$app}/"));
    $stream->save();
    // access stream for managing app roles
    $stream = new Streams_Stream();
    $stream->publisherId = $app;
    $stream->name = 'Streams/labels';
    $stream->type = 'Streams/resource';
    $stream->title = "Labels";
    $stream->setAttribute('prefixes', array("Users/", "{$app}/"));
    $stream->save();
    // access for managing app contacts
    $access = new Streams_Access();
    $access->publisherId = $communityId;
    $access->streamName = 'Streams/contacts';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
    // access for managing app roles
    $access = new Streams_Access();
    $access->publisherId = $communityId;
    $access->streamName = 'Streams/labels';
    $access->ofUserId = '';
    $access->ofContactLabel = "{$app}/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
}
Пример #3
0
function Websites_0_8_3_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    // access for managing communities
    $access = new Streams_Access();
    $access->publisherId = $app;
    $access->streamName = 'Streams/community*';
    $access->ofUserId = '';
    $access->ofContactLabel = "Websites/admins";
    $access->readLevel = Streams::$READ_LEVEL['messages'];
    $access->writeLevel = Streams::$WRITE_LEVEL['edit'];
    $access->adminLevel = Streams::$ADMIN_LEVEL['manage'];
    $access->save();
}
function Websites_0_9_1_Streams_mysql()
{
    $userId = Users::communityId();
    $ofUserId = '';
    $ofContactLabel = 'Websites/admins';
    $grantedByUserId = null;
    $streams = array("Websites/presentation/" => array('type' => "Streams/template", "title" => "Untitled Presentation", "icon" => "{{baseUrl}}/plugins/Websites/img/icons/Websites/presentation", "content" => "", "deletable" => true), "Websites/slide/" => array('type' => "Streams/template", "title" => "Untitled Slide", "icon" => "{{baseUrl}}/plugins/Websites/img/icons/Websites/presentation", "content" => "", "deletable" => true));
    $readLevel = Streams::$READ_LEVEL['messages'];
    $adminLevel = Streams::$ADMIN_LEVEL['own'];
    $rows = array();
    foreach ($streams as $streamName => $stream) {
        $publisherId = substr($streamName, -1) == '/' ? '' : $userId;
        $level = !empty($stream['deletable']) ? 'close' : 'edit';
        $writeLevel = Streams::$WRITE_LEVEL[!empty($stream['deletable']) ? 'close' : 'edit'];
        $rows[] = compact('publisherId', 'streamName', 'ofUserId', 'ofContactLabel', 'grantedByUserId', 'readLevel', 'writeLevel', 'adminLevel');
    }
    Streams_Access::insertManyAndExecute($rows);
    $attributes = null;
    $closedTime = null;
    $readLevel = Streams::$READ_LEVEL['messages'];
    $writeLevel = Streams::$WRITE_LEVEL['join'];
    $adminLevel = Streams::$ADMIN_LEVEL['invite'];
    $inheritAccess = null;
    $rows = array();
    foreach ($streams as $name => $s) {
        extract($s);
        $publisherId = substr($name, -1) == '/' ? '' : $userId;
        $rows[] = compact('publisherId', 'name', 'type', 'title', 'icon', 'content', 'attributes', 'readLevel', 'writeLevel', 'adminLevel', 'inheritAccess');
    }
    Streams_Stream::insertManyAndExecute($rows);
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Websites/presentation/', 'type' => 'slides', 'fromPublisherId' => '', 'fromStreamName' => 'Websites/slide/'))->execute();
}
function Streams_0_8_8_Streams_mysql()
{
    $communityId = Users::communityId();
    $user = Users_User::fetch($communityId, true);
    Streams::create($communityId, $communityId, 'Streams/resource', array('name' => 'Streams/invitations', 'readLevel' => 0, 'writeLevel' => 0, 'adminLevel' => 0));
    Streams_Access::insert(array('publisherId' => $communityId, 'streamName' => "Streams/invitations", 'ofUserId' => '', 'grantedByUserId' => null, 'ofContactLabel' => "{$app}/admins", 'readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['close'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']))->execute();
}
Пример #6
0
function Streams_access_put($params)
{
    $user = Users::loggedInUser(true);
    Q_Valid::nonce(true);
    $publisherId = Streams::requestedPublisherId(true);
    $streamName = Streams::requestedName(true);
    $stream = Streams::fetchOne($user->id, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'));
    }
    if (!$stream->testAdminLevel('own')) {
        throw new Users_Exception_NotAuthorized();
    }
    $p = array_merge($_REQUEST, $params);
    $access = new Streams_Access();
    $access->publisherId = $stream->publisherId;
    $access->streamName = $stream->name;
    $access->ofUserId = Q::ifset($_REQUEST, 'ofUserId', '');
    $access->ofContactLabel = Q::ifset($_REQUEST, 'ofContactLabel', '');
    if (empty($access->ofUserId) and empty($access->ofContactLabel)) {
        $fields = array('grantedByUserId', 'filter', 'readLevel', 'writeLevel', 'adminLevel', 'permissions');
        foreach ($fields as $field) {
            if (isset($p[$field])) {
                $stream->{$field} = $p[$field];
            }
        }
        $stream->save();
        return;
    }
    $access->retrieve();
    $fields = array('grantedByUserId', 'filter', 'readLevel', 'writeLevel', 'adminLevel', 'permissions');
    foreach ($fields as $field) {
        if (isset($p[$field])) {
            $access->{$field} = $p[$field];
        }
    }
    $defaults = array('grantedByUserId' => $user->id, 'readLevel' => -1, 'writeLevel' => -1, 'adminLevel' => -1);
    foreach ($defaults as $k => $v) {
        if (!isset($access->{$k})) {
            $access->{$k} = $v;
        }
    }
    $access->save();
    Streams::$cache['access'] = $access;
}
Пример #7
0
function Websites_0_8_Streams_mysql()
{
    $userId = Q_Config::get("Websites", "user", "id", null);
    if (!$userId) {
        throw new Q_Exception('Websites: Please fill in the config field "Websites"/"user"/"id"');
    }
    // $now = Streams::db()->toDateTime(Streams::db()->getCurrentTimestamp());
    $ofUserId = '';
    $ofContactLabel = 'Websites/admins';
    $grantedByUserId = null;
    $streams = array("Streams/images/" => array('type' => "Streams/template", "title" => "Images", "icon" => "default", "content" => "", "deletable" => true), "Streams/image/" => array('type' => "Streams/template", "title" => "Untitled Image", "icon" => "Streams/image", "content" => "", "deletable" => true), "Streams/file/" => array('type' => "Streams/template", "title" => "Untitled File", "icon" => "files/_blank", "content" => "", "deletable" => true), "Websites/article/" => array('type' => "Streams/template", "title" => "Untitled Article", "icon" => "default", "content" => "", "deletable" => true), "Websites/seo/" => array('type' => "Streams/template", "title" => "Website SEO", "icon" => Q_Html::themedUrl("plugins/Websites/img/seo"), "content" => "", "deletable" => true), "Websites/header" => array('type' => "Streams/image/icon", "title" => "Header image", "icon" => Q_Html::themedUrl("plugins/Websites/img/header"), "content" => ""), "Websites/slogan" => array('type' => "Streams/text/small", "title" => "Website slogan", "icon" => "default", "content" => "The coolest website"), "Websites/title" => array('type' => "Streams/text/small", "title" => "Website title", "icon" => "default", "content" => "Website Title"), "Websites/menu" => array('type' => "Streams/category", "title" => "Website Menu", "icon" => "default", "content" => ""), "Websites/articles" => array('type' => "Streams/category", "title" => "Articles", "icon" => "default", "content" => "Articles"), "Websites/images" => array('type' => "Streams/category", "title" => "Images", "icon" => "default", "content" => "Articles"));
    $readLevel = Streams::$READ_LEVEL['messages'];
    $writeLevel = Streams::$WRITE_LEVEL['edit'];
    $adminLevel = Streams::$ADMIN_LEVEL['own'];
    $rows = array();
    foreach ($streams as $streamName => $stream) {
        $publisherId = substr($streamName, -1) == '/' ? '' : $userId;
        $writeLevel = !empty($stream['deletable']) ? 40 : 30;
        $rows[] = compact('publisherId', 'streamName', 'ofUserId', 'ofContactLabel', 'grantedByUserId', 'readLevel', 'writeLevel', 'adminLevel');
    }
    Streams_Access::insertManyAndExecute($rows);
    $attributes = null;
    $closedTime = null;
    $readLevel = Streams::$READ_LEVEL['messages'];
    $writeLevel = Streams::$WRITE_LEVEL['join'];
    $adminLevel = Streams::$ADMIN_LEVEL['invite'];
    $inheritAccess = null;
    $rows = array();
    foreach ($streams as $name => $s) {
        extract($s);
        if (substr($name, 0, 9) != 'Websites/') {
            continue;
            // this tempate was already added by Streams install script
        }
        $publisherId = substr($name, -1) == '/' ? '' : $userId;
        $rows[] = compact('publisherId', 'name', 'type', 'title', 'icon', 'content', 'attributes', 'readLevel', 'writeLevel', 'adminLevel', 'inheritAccess');
    }
    Streams_Stream::insertManyAndExecute($rows);
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/images/', 'type' => 'images', 'fromPublisherId' => '', 'fromStreamName' => 'Streams/image/'))->execute();
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/category/', 'type' => 'articles', 'fromPublisherId' => '', 'fromStreamName' => 'Websites/article/'))->execute();
    Streams_RelatedTo::insert(array('toPublisherId' => '', 'toStreamName' => 'Streams/category/', 'type' => 'announcements', 'fromPublisherId' => '', 'fromStreamName' => 'Websites/article/'))->execute();
}
Пример #8
0
function Streams_0_8_7_Streams_mysql()
{
    $app = Q_Config::expect('Q', 'app');
    $user = Users_User::fetch($app, true);
    $simulated = array('row' => $user, 'inserted' => true, 'modifiedFields' => $user->fields);
    Q::event('Db/Row/Users_User/saveExecute', $simulated, 'after');
    $stream = array('publisherId' => '', 'name' => "Streams/images/", 'type' => 'Streams/template', 'title' => 'Image Gallery', 'icon' => 'default', 'content' => '', 'attributes' => null, 'readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['close'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']);
    $access = array('publisherId' => '', 'streamName' => "Streams/images/", 'ofUserId' => '', 'grantedByUserId' => null, 'ofContactLabel' => "{$app}/admins", 'readLevel' => Streams::$READ_LEVEL['messages'], 'writeLevel' => Streams::$WRITE_LEVEL['close'], 'adminLevel' => Streams::$ADMIN_LEVEL['invite']);
    Streams_Stream::insert($stream)->execute();
    Streams_Access::insert($access)->execute();
    $stream['name'] = $access['streamName'] = 'Streams/image/';
    $stream['icon'] = 'Streams/image';
    $stream['title'] = 'Untitled Image';
    Streams_Stream::insert($stream)->execute();
    Streams_Access::insert($access)->execute();
    $stream['name'] = $access['streamName'] = 'Streams/file/';
    $stream['icon'] = 'files/_blank';
    $stream['title'] = 'Untitled File';
    Streams_Stream::insert($stream)->execute();
    Streams_Access::insert($access)->execute();
}
function Streams_after_Users_User_saveExecute($params)
{
    // If the username or icon was somehow modified,
    // update all the avatars for this publisher
    $modifiedFields = $params['modifiedFields'];
    $user = $params['row'];
    $updates = array();
    if (isset($modifiedFields['username'])) {
        $updates['username'] = $modifiedFields['username'];
    }
    if (isset($modifiedFields['icon'])) {
        $updates['icon'] = $modifiedFields['icon'];
    }
    if ($user->id === Users::communityId()) {
        $firstName = Users::communityName();
        $lastName = Users::communitySuffix();
        $firstName = $firstName ? $firstName : "";
        $lastName = $lastName ? $lastName : "";
    } else {
        $firstName = Q::ifset(Streams::$cache, 'register', 'first', '');
        $lastName = Q::ifset(Streams::$cache, 'register', 'last', '');
    }
    if ($params['inserted']) {
        // create some standard streams for them
        $onInsert = Q_Config::get('Streams', 'onInsert', 'Users_User', array());
        if (!$onInsert) {
            return;
        }
        $p = new Q_Tree();
        $p->load(STREAMS_PLUGIN_CONFIG_DIR . DS . 'streams.json');
        $p->load(APP_CONFIG_DIR . DS . 'streams.json');
        $values = array('Streams/user/firstName' => $firstName, 'Streams/user/lastName' => $lastName);
        // Check for user data from facebook
        if (!empty(Users::$cache['facebookUserData'])) {
            $userData = Users::$cache['facebookUserData'];
            foreach ($userData as $name_fb => $value) {
                foreach ($p->getAll() as $name => $info) {
                    if (isset($info['name_fb']) and $info['name_fb'] === $name_fb) {
                        $onInsert[] = $name;
                        $values[$name] = $value;
                    }
                }
            }
        }
        foreach ($onInsert as $name) {
            $stream = Streams::fetchOne($user->id, $user->id, $name);
            if (!$stream) {
                // it shouldn't really be in the db yet
                $stream = new Streams_Stream();
                $stream->publisherId = $user->id;
                $stream->name = $name;
            }
            $stream->type = $p->expect($name, "type");
            $stream->title = $p->expect($name, "title");
            $stream->content = $p->get($name, "content", '');
            // usually empty
            $stream->readLevel = $p->get($name, 'readLevel', Streams_Stream::$DEFAULTS['readLevel']);
            $stream->writeLevel = $p->get($name, 'writeLevel', Streams_Stream::$DEFAULTS['writeLevel']);
            $stream->adminLevel = $p->get($name, 'adminLevel', Streams_Stream::$DEFAULTS['adminLevel']);
            if ($name === "Streams/user/icon") {
                $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                sort($sizes);
                $stream->setAttribute('sizes', $sizes);
                $stream->icon = $user->iconUrl();
            }
            if (isset($values[$name])) {
                $stream->content = $values[$name];
            }
            $stream->save();
            // this also inserts avatars
            $o = array('userId' => $user->id, 'skipAccess' => true);
            $so = $p->get($name, "subscribe", array());
            if ($so === false) {
                $stream->join($o);
            } else {
                $stream->subscribe(array_merge($o, $so));
            }
        }
        // Save a greeting stream, to be edited
        $communityId = Users::communityId();
        Streams::create($user->id, $user->id, "Streams/greeting", array('name' => "Streams/greeting/{$communityId}"));
        // Create some standard labels
        $label = new Users_Label();
        $label->userId = $user->id;
        $label->label = 'Streams/invited';
        $label->icon = 'labels/Streams/invited';
        $label->title = 'People I invited';
        $label->save(true);
        $label2 = new Users_Label();
        $label2->userId = $user->id;
        $label2->label = 'Streams/invitedMe';
        $label2->icon = 'labels/Streams/invitedMe';
        $label2->title = 'Who invited me';
        $label2->save(true);
        // By default, users they invite should see their full name
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/firstName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        $access = new Streams_Access();
        $access->publisherId = $user->id;
        $access->streamName = 'Streams/user/lastName';
        $access->ofUserId = '';
        $access->ofContactLabel = 'Streams/invited';
        $access->grantedByUserId = $user->id;
        $access->readLevel = Streams::$READ_LEVEL['content'];
        $access->writeLevel = -1;
        $access->adminLevel = -1;
        $access->save();
        // NOTE: the above saving of access caused Streams::updateAvatar to run,
        // insert a Streams_Avatar row for the new user, and properly configure it.
    } else {
        if ($modifiedFields) {
            if ($updates) {
                Streams_Avatar::update()->set($updates)->where(array('publisherId' => $user->id))->execute();
            }
            foreach ($modifiedFields as $field => $value) {
                $name = Q_Config::get('Streams', 'onUpdate', 'Users_User', $field, null);
                if (!$name) {
                    continue;
                }
                $stream = isset(Streams::$beingSaved[$field]) ? Streams::$beingSaved[$field] : Streams::fetchOne($user->id, $user->id, $name);
                if (!$stream) {
                    // it should probably already be in the db
                    continue;
                }
                $stream->content = $value;
                if ($name === "Streams/user/icon") {
                    $sizes = Q_Config::expect('Users', 'icon', 'sizes');
                    sort($sizes);
                    $attributes = $stream->attributes;
                    $stream->setAttribute('sizes', $sizes);
                    $stream->icon = $changes['icon'] = $user->iconUrl();
                }
                Streams::$beingSavedQuery = $stream->changed($user->id);
            }
        }
    }
}
Пример #10
0
function Streams_before_Q_objects()
{
    $token = Q_Request::special('Streams.token', null);
    if ($token === null) {
        return;
    }
    $invite = Streams_Invite::fromToken($token);
    if (!$invite) {
        throw new Q_Exception_MissingRow(array('table' => 'invite', 'criteria' => "token = '{$token}"), 'token');
    }
    // did invite expire?
    $ts = Streams_Invite::db()->select("CURRENT_TIMESTAMP")->fetchAll(PDO::FETCH_NUM);
    if (isset($invite->expireTime) and $invite->expireTime < $ts[0][0]) {
        $invite->state = 'expired';
        $invite->save();
    }
    // is invite still pending?
    if ($invite->state !== 'pending') {
        switch ($invite->state) {
            case 'expired':
                $exception = new Streams_Exception_AlreadyExpired(null, 'token');
                break;
            case 'accepted':
                $exception = new Streams_Exception_AlreadyAccepted(null, 'token');
                break;
            case 'declined':
                $exception = new Streams_Exception_AlreadyDeclined(null, 'token');
                break;
            case 'forwarded':
                $exception = new Streams_Exception_AlreadyForwarded(null, 'token');
                break;
            default:
                $exception = new Q_Exception("This invite has already been " . $invite->state, 'token');
                break;
        }
        $shouldThrow = Q::event('Streams/objects/inviteException', compact('invite', 'exception'), 'before');
        if ($shouldThrow === null) {
            Q_Response::setNotice('Streams/objects', $exception->getMessage(), true);
        } else {
            if ($shouldThrow === true) {
                throw $exception;
            }
        }
    }
    // now process the invite
    $invitedUser = Users_User::fetch($invite->userId, true);
    $stream = Streams::fetchOne($invitedUser->id, $invite->publisherId, $invite->streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "publisherId = '{$invite->publisherId}', name = '{$invite->streamName}'"));
    }
    $byUser = Users_User::fetch($invite->invitingUserId, true);
    $byStream = Streams::fetchOne($byUser->id, $invite->publisherId, $invite->streamName);
    if (!$byStream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => "publisherId = '{$invite->publisherId}', name = '{$invite->streamName}'"));
    }
    $access = new Streams_Access();
    $access->publisherId = $byStream->publisherId;
    $access->streamName = $byStream->name;
    $access->ofUserId = $invite->userId;
    $specified_access = false;
    foreach (array('readLevel', 'writeLevel', 'adminLevel') as $level_type) {
        $access->{$level_type} = -1;
        if (empty($invite->{$level_type})) {
            continue;
        }
        // Give access level from the invite.
        // However, if inviting user has a lower access level now,
        // then give that level instead, unless it is lower than
        // what the invited user would have had otherwise.
        $min = min($invite->{$level_type}, $byStream->get($level_type, 0));
        if ($min > $stream->get($level_type, 0)) {
            $access->{$level_type} = $min;
            $specified_access = true;
        }
    }
    if ($specified_access) {
        $access->save(true);
    }
    // now log invited user in
    $user = Users::loggedInUser();
    if (empty($user) or $user->id !== $invite->userId) {
        $user = new Users_User();
        $user->id = $invite->userId;
        if (!$user->retrieve()) {
            // The user who was invited doesn't exist
            // This shouldn't happen. We just silently log it and return.
            Q::log("Sanity check failed: invite with {$invite->token} pointed to nonexistent user");
            return;
        }
        Users::setLoggedInUser($user);
    }
    // accept invite and autosubscribe if first time
    if ($invite->accept() and !$stream->subscription($user->id)) {
        $stream->subscribe();
    }
    // retain the invite object for further processing
    Streams::$followedInvite = $invite;
}
Пример #11
0
 /**
  * Starts a recurring subscription
  * @param {Streams_Stream} $plan The subscription plan stream
  * @param {string} [$payments=null] The type of payments processor, could be "authnet" or "stripe". If omitted, the subscription proceeds without any payments.
  * @param {array} [$options=array()] Options for the subscription
  * @param {date} [$options.startDate=today] The start date of the subscription
  * @param {date} [$options.endDate=today+year] The end date of the subscription
  * @param {Users_User} [$options.user=Users::loggedInUser()] Allows us to set the user to subscribe
  * @param {Users_User} [$options.publisherId=Users::communityId()] Allows us to override the publisher to subscribe to
  * @param {string} [$options.description=null] description of the charge, to be sent to customer
  * @param {string} [$options.metadata=null] any additional metadata to store with the charge
  * @param {string} [$options.subscription=null] if this charge is related to a subscription stream
  * @param {string} [$options.subscription.publisherId]
  * @param {string} [$options.subscription.streamName]
  * @throws Assets_Exception_DuplicateTransaction
  * @throws Assets_Exception_HeldForReview
  * @throws Assets_Exception_ChargeFailed
  * @return {Streams_Stream} A stream of type 'Assets/subscription' representing this subscription
  */
 static function startSubscription($plan, $payments = null, $options = array())
 {
     if (!isset($options['user'])) {
         $options['user'] = Users::loggedInUser(true);
     }
     $app = Q_Config::expect('Q', 'app');
     $user = Q::ifset($options, 'user', Users::loggedInUser(true));
     $currency = 'USD';
     // TODO: may want to implement support for currency conversion
     $startDate = Q::ifset($options, 'startDate', date("Y-m-d"));
     $startDate = date('Y-m-d', strtotime($startDate));
     $months = $plan->getAttribute('months', 12);
     $amount = $plan->getAttribute('amount');
     $endDate = date("Y-m-d", strtotime("-1 day", strtotime("+{$months} month", strtotime($startDate))));
     $endDate = date('Y-m-d', strtotime($endDate));
     $publisherId = Q::ifset($options, 'publisherId', Users::communityId());
     $publisher = Users_User::fetch($publisherId);
     $streamName = "Assets/subscription/{$user->id}/{$plan->name}";
     if ($subscription = Streams::fetchOne($publisherId, $publisherId, $streamName)) {
         return $subscription;
         // it already started
     }
     $attributes = Q::json_encode(array('payments' => $payments, 'planPublisherId' => $plan->publisherId, 'planStreamName' => $plan->name, 'startDate' => $startDate, 'endDate' => $endDate, 'months' => $months, 'amount' => $amount, 'currency' => $currency));
     $stream = Streams::create($publisherId, $publisherId, "Assets/subscription", array('name' => $streamName, 'title' => $plan->title, 'readLevel' => Streams::$READ_LEVEL['none'], 'writeLevel' => Streams::$WRITE_LEVEL['none'], 'adminLevel' => Streams::$ADMIN_LEVEL['none'], 'attributes' => $attributes));
     $access = new Streams_Access(array('publisherId' => $publisherId, 'streamName' => $streamName, 'ofUserId' => $user->id, 'grantedByUserId' => $app, 'readLevel' => Streams::$READ_LEVEL['max'], 'writeLevel' => -1, 'adminLevel' => -1));
     $access->save();
     $amount = $plan->getAttribute('amount', null);
     if (!is_numeric($amount)) {
         throw new Q_Exception_WrongValue(array('field' => 'amount', 'range' => 'an integer'));
     }
     $options['stream'] = $stream;
     if ($payments) {
         Assets::charge($payments, $amount, $currency, $options);
     }
     /**
      * @event Assets/startSubscription {before}
      * @param {Streams_Stream} plan
      * @param {Streams_Stream} subscription
      * @param {string} startDate
      * @param {string} endDate
      * @return {Users_User}
      */
     Q::event('Assets/startSubscription', compact('plan', 'user', 'publisher', 'stream', 'startDate', 'endDate', 'months', 'currency'), 'after');
     return $stream;
 }
Пример #12
0
 /**
  * @method afterRemoveExcecute
  * @param {Db_Result} $result
  * @param {Db_Query} $query
  * @return {Db_Result}
  */
 function afterRemoveExecute($result, $query)
 {
     $stream = $this;
     // if the above call threw an exception, then we will not be doing the following.
     Q_Utils::sendToNode(array("Q/method" => "Streams/Stream/remove", "stream" => Q::json_encode($stream->toArray())));
     /**
      * @event Streams/remove/$streamType {after}
      * @param {Streams_Stream} stream
      * @param {string} asUserId
      */
     Q::event("Streams/remove/{$stream->type}", compact('stream', 'result'), 'after');
     if ($this->name !== 'Streams/user/firstName' and $this->name !== 'Streams/user/lastName') {
         return $result;
     }
     // Update all avatars corresponding to access rows for this stream
     $taintedAccess = Streams_Access::select('*')->where(array('publisherId' => $this->publisherId, 'streamName' => $this->name))->fetchDbRows();
     Streams::updateAvatars($this->publisherId, $taintedAccess, $this, true);
     return $result;
 }
Пример #13
0
 /**
  * Calculates the access for one or more streams by querying the database
  * Modifies the objects in the $streams array, setting their access levels.
  * After the function returns, you will be able to call the methods
  * testReadLevel(), testWriteLevel() and testAdminLevel()
  * on these streams before using them on the user's behalf.
  * @method fetch
  * @static
  * @param {string} $asUserId
  *  Set this to the user relative to whom access is calculated.
  *  If this matches the publisherId, just sets full access and calls publishedByFetcher(true).
  *  If this is '', only returns the streams anybody can see.
  *  If this is null, the logged-in user's id is used, or '' if no one is logged in
  * @param {string} $publisherId
  *  The id of the user publishing these streams
  * @param {array} $streams
  *  An array of streams, obtained for example by Streams::fetch
  * @param {boolean} $recalculate=false
  *  Pass true here to force recalculating access to streams for which access was already calculated
  * @return {integer}
  *  The number of streams that were recalculated
  */
 static function calculateAccess($asUserId, $publisherId, $streams, $recalculate = false)
 {
     if (!isset($asUserId)) {
         $asUserId = Users::loggedInUser();
         if (!$asUserId) {
             $asUserId = "";
         }
     }
     if ($asUserId instanceof Users_User) {
         $asUserId = $asUserId->id;
     }
     if ($publisherId instanceof Users_User) {
         $publisherId = $publisherId->id;
     }
     if ($recalculate) {
         $streams2 = $streams;
     } else {
         $streams2 = array();
         foreach ($streams as $k => $s) {
             if ($s->get('readLevel', null) === null) {
                 $streams2[$k] = $s;
             }
         }
     }
     if (empty($streams2)) {
         return 0;
     }
     $public_source = Streams::$ACCESS_SOURCES['public'];
     $contact_source = Streams::$ACCESS_SOURCES['contact'];
     $direct_source = Streams::$ACCESS_SOURCES['direct'];
     $streams3 = array();
     $names = array();
     foreach ($streams2 as $s) {
         if ($s->get('asUserId', null) === $asUserId) {
             continue;
         }
         $s->set('asUserId', $asUserId);
         if ($asUserId and $asUserId == $publisherId) {
             // The publisher should have full access to every one of their streams.
             // Streams which are "required", though, won't be deleted by the system.
             $required = Q_Config::get('Streams', 'requiredUserStreams', $s->name, false);
             $s->set('isRequired', $required);
             $s->set('readLevel', Streams::$READ_LEVEL['max']);
             $s->set('writeLevel', Streams::$WRITE_LEVEL['max']);
             $s->set('adminLevel', Streams::$ADMIN_LEVEL['max']);
             $s->set('readLevel_source', $direct_source);
             $s->set('writeLevel_source', $direct_source);
             $s->set('adminLevel_source', $direct_source);
             $s->publishedByFetcher(true);
             continue;
         }
         $s->set('readLevel', $s->readLevel);
         $s->set('writeLevel', $s->writeLevel);
         $s->set('adminLevel', $s->adminLevel);
         $s->set('readLevel_source', $public_source);
         $s->set('writeLevel_source', $public_source);
         $s->set('adminLevel_source', $public_source);
         if (empty($asUserId)) {
             continue;
             // No need to fetch further access info.
         }
         $names[] = $s->name;
         $names[] = $s->type . "*";
         $streams3[] = $s;
     }
     if (empty($names)) {
         return count($streams2);
     }
     // Get the per-label access data
     // Avoid making a join to allow more flexibility for sharding
     $accesses = Streams_Access::select('*')->where(array('publisherId' => $publisherId, 'streamName' => $names, 'ofUserId' => array('', $asUserId)))->fetchDbRows();
     $labels = array();
     foreach ($accesses as $access) {
         if ($access->ofContactLabel) {
             $labels[] = $access->ofContactLabel;
         }
     }
     if (!empty($labels)) {
         $labels = array_unique($labels);
         $contacts = Users_Contact::select('*')->where(array('userId' => $publisherId, 'label' => $labels, 'contactUserId' => $asUserId))->fetchDbRows();
         foreach ($contacts as $contact) {
             foreach ($accesses as $access) {
                 if ($access->ofContactLabel !== $contact->label) {
                     continue;
                 }
                 foreach ($streams3 as $stream) {
                     $tail = substr($access->streamName, -1);
                     $head = substr($access->streamName, 0, -1);
                     if ($stream->name !== $access->streamName and ($tail !== '*' or $head !== $stream->type)) {
                         continue;
                     }
                     $readLevel = $stream->get('readLevel', 0);
                     $writeLevel = $stream->get('writeLevel', 0);
                     $adminLevel = $stream->get('adminLevel', 0);
                     if ($access->readLevel >= 0 and $access->readLevel > $readLevel) {
                         $stream->set('readLevel', $access->readLevel);
                         $stream->set('readLevel_source', $contact_source);
                     }
                     if ($access->writeLevel >= 0 and $access->writeLevel > $writeLevel) {
                         $stream->set('writeLevel', $access->writeLevel);
                         $stream->set('writeLevel_source', $contact_source);
                     }
                     if ($access->adminLevel >= 0 and $access->adminLevel > $adminLevel) {
                         $stream->set('adminLevel', $access->adminLevel);
                         $stream->set('adminLevel_source', $contact_source);
                     }
                 }
             }
         }
     }
     // Override with per-user access data
     foreach ($accesses as $access) {
         foreach ($streams3 as $stream) {
             $tail = substr($access->streamName, -1);
             $head = substr($access->streamName, 0, -1);
             if ($stream->name !== $access->streamName and ($tail !== '*' or $head !== $stream->type)) {
                 continue;
             }
             if ($access->ofUserId === $asUserId) {
                 if ($access->readLevel >= 0) {
                     $stream->set('readLevel', $access->readLevel);
                     $stream->set('readLevel_source', $direct_source);
                 }
                 if ($access->writeLevel >= 0) {
                     $stream->set('writeLevel', $access->writeLevel);
                     $stream->set('writeLevel_source', $direct_source);
                 }
                 if ($access->adminLevel >= 0) {
                     $stream->set('adminLevel', $access->adminLevel);
                     $stream->set('adminLevel_source', $direct_source);
                 }
             }
         }
     }
     return count($streams2);
 }
Пример #14
0
/**
 * Access tool
 * @class Streams access
 * @constructor
 * @param {array} $options Options for the tool
 * @param {string} [$options.publisherId] the id of the user who is publishing the stream
 * @param {string} [$options.streamName] the name of the stream for which to edit access levels
 * @param {array} [$options.tabs] array of tab name => title. Defaults to read, write, admin tabs.
 * @param {array} [$options.ranges] associative array with keys "read", "write", "admin" and values as associative arrays of ($min, $max) for the displayed levels.
 * @param {boolean} [$options.controls] optionally set this to true to render only the controls
 */
function Streams_access_tool($options)
{
    $tabs = array('read' => 'visible to', 'write' => 'editable by', 'admin' => 'members');
    extract($options);
    $user = Users::loggedInUser(true);
    /**
     * @var string $streamName
     */
    if (empty($streamName)) {
        $streamName = Streams::requestedName(true);
    }
    if (empty($publisherId)) {
        $publisherId = Streams::requestedPublisherId();
        if (empty($publisherId)) {
            $publisherId = $user->id;
        }
    }
    reset($tabs);
    $tab = Q::ifset($_REQUEST, 'tab', key($tabs));
    $stream = Streams::fetchOne($user->id, $publisherId, $streamName);
    if (!$stream) {
        throw new Q_Exception_MissingRow(array('table' => 'stream', 'criteria' => 'with that name'));
    }
    $stream->addPreloaded($user->id);
    if (!$stream->testAdminLevel('own')) {
        throw new Users_Exception_NotAuthorized();
    }
    $access_array = Streams_Access::select('*')->where(array('publisherId' => $stream->publisherId, 'streamName' => $stream->name))->andWhere("{$tab}Level != -1")->fetchDbRows();
    $labelRows = Users_Label::fetch($stream->publisherId, '', true);
    $labels = array();
    $icons = array();
    foreach ($labelRows as $label => $row) {
        $labels[$label] = $row->title;
        $icons[$label] = "labels/{$label}";
    }
    $userId_list = array();
    foreach ($access_array as $a) {
        if ($a->ofUserId) {
            $userId_list[] = $a->ofUserId;
        }
    }
    $avatar_array = empty($userId_list) ? array() : Streams_Avatar::fetch($user->id, $userId_list);
    switch ($tab) {
        case 'read':
            $levels = Q_Config::get('Streams', 'readLevelOptions', array());
            break;
        case 'write':
            $levels = Q_Config::get('Streams', 'writeLevelOptions', array());
            break;
        case 'admin':
            $levels = Q_Config::get('Streams', 'adminLevelOptions', array());
            break;
    }
    if (isset($ranges[$tab])) {
        $range_min = reset($ranges[$tab]);
        $range_max = end($ranges[$tab]);
        foreach ($levels as $k => $v) {
            if ($k < $range_min) {
                unset($levels[$k]);
            }
            if ($k > $range_max) {
                unset($levels[$k]);
            }
        }
    }
    $accessActionUrl = Q_Uri::url("Streams/access?publisherId={$publisherId}&streamName={$streamName}");
    $dir = Q_Config::get('Users', 'paths', 'icons', 'files/Users/icons');
    $accessArray = Db::exportArray($access_array);
    $avatarArray = Db::exportArray($avatar_array);
    if (empty($controls)) {
        Q_Response::addScript("plugins/Streams/js/Streams.js");
        Q_Response::addScript("plugins/Streams/js/tools/access.js");
        Q_Response::setToolOptions(compact('accessArray', 'avatarArray', 'labels', 'icons', 'tab', 'publisherId', 'streamName'));
    } else {
        Q_Response::setSlot('extra', array('stream' => $stream->exportArray(), 'accessArray' => $accessArray, 'avatarArray' => $avatarArray, 'labels' => $labels, 'icons' => $icons));
    }
    return Q::view('Streams/tool/access.php', compact('stream', 'tabs', 'tab', 'labels', 'icons', 'levels', 'dir', 'publisherId', 'streamName', 'accessActionUrl', 'controls'));
}
Пример #15
0
 /**
  * Keeps Access table consistent on row deletion and update avatar
  * @method afterRemoveExecute
  * @param {Db_Result} $result
  *	Query result
  * @param {array} $query
  *	The query which has been excecuted
  * @return {Db_Result}
  */
 function afterRemoveExecute($result, $query)
 {
     if (!empty($this->ofUserId)) {
         // Removed an access for a specific user
         Streams::updateAvatar($this->ofUserId, $this->publisherId);
         return $result;
     }
     if (empty($this->ofContactLabel)) {
         return $result;
     }
     // Update all avatars corresponding to access rows for this stream
     $tainted_access = Streams_Access::select('*')->where(array('publisherId' => $this->publisherId, 'streamName' => $this->streamName))->fetchDbRows();
     $found = false;
     foreach ($tainted_access as $ca) {
         if ($ca->ofContactLabel === $this->ofContactLabel) {
             // this should never really happen, since the row was just deleted
             $found = true;
             $ca->set('removed', true);
         }
     }
     if (!$found) {
         $this->set('removed', true);
         $tainted_access[] = $this;
     }
     Streams::updateAvatars($this->publisherId, $tainted_access, $this->streamName);
     return $result;
 }